From 22475d77da2dcc39cbd632f49dcbcda864872a43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20Ca=C3=B1as=20Vargas?= Date: Mon, 16 Jan 2017 01:51:01 +0100 Subject: [PATCH] Version 16.117 --- swad_ID.c | 21 ++++---- swad_assignment.c | 4 +- swad_attendance.c | 12 +++-- swad_changelog.h | 3 +- swad_country.c | 71 +++++++++++++++----------- swad_file.c | 8 ++- swad_file.h | 6 ++- swad_file_browser.c | 34 ++++++------ swad_group.c | 10 ++-- swad_mail.c | 17 +++--- swad_message.c | 8 +-- swad_photo.c | 8 +-- swad_record.c | 5 +- swad_search.c | 25 ++++----- swad_search.h | 3 +- swad_statistic.c | 72 ++++++++++++++------------ swad_string.c | 10 ++-- swad_survey.c | 4 +- swad_syllabus.c | 21 +++++--- swad_syllabus.h | 2 +- swad_test.c | 122 +++++++++++++++++++++++--------------------- swad_user.c | 84 +++++++++++++++++------------- swad_web_service.c | 41 +++++++++------ swad_zip.c | 12 ++--- 24 files changed, 331 insertions(+), 272 deletions(-) diff --git a/swad_ID.c b/swad_ID.c index 2cf29d00..c185e1e6 100644 --- a/swad_ID.c +++ b/swad_ID.c @@ -177,7 +177,7 @@ unsigned ID_GetListUsrCodsFromUsrID (struct UsrData *UsrDat, char *Query; MYSQL_RES *mysql_res; MYSQL_ROW row; - size_t Length; + size_t MaxLength; unsigned NumID; unsigned NumUsr; bool CheckPassword = false; @@ -189,40 +189,41 @@ unsigned ID_GetListUsrCodsFromUsrID (struct UsrData *UsrDat, CheckPassword = true; /***** Allocate memory for query string *****/ - Length = 512 + UsrDat->IDs.Num * (1 + ID_MAX_LENGTH_USR_ID + 1) - 1; - if ((Query = (char *) malloc (Length + 1)) == NULL) + MaxLength = 512 + UsrDat->IDs.Num * (1 + ID_MAX_LENGTH_USR_ID + 1) - 1; + if ((Query = (char *) malloc (MaxLength + 1)) == NULL) Lay_ShowErrorAndExit ("Not enough memory to store list of user's IDs."); /***** Get user's code(s) from database *****/ Str_Copy (Query,CheckPassword ? "SELECT DISTINCT(usr_IDs.UsrCod) FROM usr_IDs,usr_data" " WHERE usr_IDs.UsrID IN (" : "SELECT DISTINCT(UsrCod) FROM usr_IDs" - " WHERE UsrID IN (",Length); + " WHERE UsrID IN (",MaxLength); for (NumID = 0; NumID < UsrDat->IDs.Num; NumID++) { if (NumID) - strcat (Query,","); + Str_Concat (Query,",",MaxLength); sprintf (SubQuery,"'%s'",UsrDat->IDs.List[NumID].ID); - strcat (Query,SubQuery); + + Str_Concat (Query,SubQuery,MaxLength); } - strcat (Query,")"); + Str_Concat (Query,")",MaxLength); if (CheckPassword) { if (OnlyConfirmedIDs) - strcat (Query," AND usr_IDs.Confirmed='Y'"); + Str_Concat (Query," AND usr_IDs.Confirmed='Y'",MaxLength); // Get user's code if I have written the correct password // or if password in database is empty (new user) sprintf (SubQuery," AND usr_IDs.UsrCod=usr_data.UsrCod" " AND (usr_data.Password='%s' OR usr_data.Password='')", EncryptedPassword); - strcat (Query,SubQuery); + Str_Concat (Query,SubQuery,MaxLength); } else if (OnlyConfirmedIDs) - strcat (Query," AND Confirmed='Y'"); + Str_Concat (Query," AND Confirmed='Y'",MaxLength); ListUsrCods->NumUsrs = (unsigned) DB_QuerySELECT (Query,&mysql_res,"can not get user's codes"); diff --git a/swad_assignment.c b/swad_assignment.c index 2ca78a08..098066f6 100644 --- a/swad_assignment.c +++ b/swad_assignment.c @@ -456,8 +456,8 @@ static void Asg_WriteAsgAuthor (struct Assignment *Asg) Str_Copy (Surnames,UsrDat.Surname1,Usr_MAX_BYTES_SURNAMES); if (UsrDat.Surname2[0]) { - strcat (Surnames," "); - strcat (Surnames,UsrDat.Surname2); + Str_Concat (Surnames," ",Usr_MAX_BYTES_SURNAMES); + Str_Concat (Surnames,UsrDat.Surname2,Usr_MAX_BYTES_SURNAMES); } Str_LimitLengthHTMLStr (FirstName,8); Str_LimitLengthHTMLStr (Surnames,8); diff --git a/swad_attendance.c b/swad_attendance.c index 347b423a..a6310c71 100644 --- a/swad_attendance.c +++ b/swad_attendance.c @@ -496,8 +496,8 @@ static void Att_WriteAttEventAuthor (struct AttendanceEvent *Att) Str_Copy (Surnames,UsrDat.Surname1,Usr_MAX_BYTES_SURNAMES); if (UsrDat.Surname2[0]) { - strcat (Surnames," "); - strcat (Surnames,UsrDat.Surname2); + Str_Concat (Surnames," ",Usr_MAX_BYTES_SURNAMES); + Str_Concat (Surnames,UsrDat.Surname2,Usr_MAX_BYTES_SURNAMES); } Str_LimitLengthHTMLStr (FirstName,8); Str_LimitLengthHTMLStr (Surnames,8); @@ -2404,11 +2404,13 @@ static unsigned Att_GetNumStdsFromAListWhoAreInAttEvent (long AttCod,long LstSel char SubQuery[1+1+10+1]; unsigned NumStd; unsigned NumStdsInAttEvent = 0; + size_t MaxLength; if (NumStdsInList) { /***** Allocate space for query *****/ - if ((Query = (char *) malloc ((size_t) (256+NumStdsInList*(1+1+10)))) == NULL) + MaxLength = 256 + NumStdsInList * (1 + 1 + 10); + if ((Query = (char *) malloc (MaxLength + 1)) == NULL) Lay_ShowErrorAndExit ("Not enough memory for query."); /***** Count number of students registered in an event in database *****/ @@ -2424,9 +2426,9 @@ static unsigned Att_GetNumStdsFromAListWhoAreInAttEvent (long AttCod,long LstSel NumStd ? ",%ld" : "%ld", LstSelectedUsrCods[NumStd]); - strcat (Query,SubQuery); + Str_Concat (Query,SubQuery,MaxLength); } - strcat (Query,") AND Present='Y'"); + Str_Concat (Query,") AND Present='Y'",MaxLength); NumStdsInAttEvent = (unsigned) DB_QueryCOUNT (Query,"can not get number of students from a list who are registered in an event"); diff --git a/swad_changelog.h b/swad_changelog.h index 341b87ed..87f70f2f 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -189,13 +189,14 @@ /****************************** Public constants *****************************/ /*****************************************************************************/ -#define Log_PLATFORM_VERSION "SWAD 16.116 (2017-01-15)" +#define Log_PLATFORM_VERSION "SWAD 16.117 (2017-01-16)" #define CSS_FILE "swad16.111.5.css" #define JS_FILE "swad16.114.js" // Number of lines (includes comments but not blank lines) has been got with the following command: // nl swad*.c swad*.h css/swad*.css py/swad*.py js/swad*.js soap/swad*?.h sql/swad*.sql | tail -1 /* + Version 16.117: Jan 16, 2017 Code refactoring related to string concatenation. (211244 lines) Version 16.116: Jan 15, 2017 Code refactoring related to string copy. (211195 lines) Version 16.115: Jan 15, 2017 Code refactoring related to string copy. (211046 lines) Version 16.114.3: Jan 15, 2017 Fixed bug in chat. (211412 lines) diff --git a/swad_country.c b/swad_country.c index 9acf1c51..df9a2d7d 100644 --- a/swad_country.c +++ b/swad_country.c @@ -930,16 +930,18 @@ void Cty_EditCountries (void) /************************** List all the countries ***************************/ /*****************************************************************************/ +#define Cty_MAX_LENGTH_SUBQUERY_CTYS ((1 + Txt_NUM_LANGUAGES) * 32) + void Cty_GetListCountries (Cty_GetExtraData_t GetExtraData) { extern const char *Txt_STR_LANG_ID[1+Txt_NUM_LANGUAGES]; char StrField[32]; - char SubQueryNam1[(1+Txt_NUM_LANGUAGES)*32]; - char SubQueryNam2[(1+Txt_NUM_LANGUAGES)*32]; - char SubQueryWWW1[(1+Txt_NUM_LANGUAGES)*32]; - char SubQueryWWW2[(1+Txt_NUM_LANGUAGES)*32]; + char SubQueryNam1[Cty_MAX_LENGTH_SUBQUERY_CTYS + 1]; + char SubQueryNam2[Cty_MAX_LENGTH_SUBQUERY_CTYS + 1]; + char SubQueryWWW1[Cty_MAX_LENGTH_SUBQUERY_CTYS + 1]; + char SubQueryWWW2[Cty_MAX_LENGTH_SUBQUERY_CTYS + 1]; char OrderBySubQuery[256]; - char Query[1024+(1+Txt_NUM_LANGUAGES)*32*4]; + char Query[1024 + Cty_MAX_LENGTH_SUBQUERY_CTYS * 4]; MYSQL_RES *mysql_res; MYSQL_ROW row; unsigned long NumRows; @@ -967,17 +969,17 @@ void Cty_GetListCountries (Cty_GetExtraData_t GetExtraData) { sprintf (StrField,"countries.Name_%s,", Txt_STR_LANG_ID[Lan]); - strcat (SubQueryNam1,StrField); + Str_Concat (SubQueryNam1,StrField,Cty_MAX_LENGTH_SUBQUERY_CTYS); sprintf (StrField,"Name_%s,", Txt_STR_LANG_ID[Lan]); - strcat (SubQueryNam2,StrField); + Str_Concat (SubQueryNam2,StrField,Cty_MAX_LENGTH_SUBQUERY_CTYS); sprintf (StrField,"countries.WWW_%s,", Txt_STR_LANG_ID[Lan]); - strcat (SubQueryWWW1,StrField); + Str_Concat (SubQueryWWW1,StrField,Cty_MAX_LENGTH_SUBQUERY_CTYS); sprintf (StrField,"WWW_%s,", Txt_STR_LANG_ID[Lan]); - strcat (SubQueryWWW2,StrField); + Str_Concat (SubQueryWWW2,StrField,Cty_MAX_LENGTH_SUBQUERY_CTYS); } switch (Gbl.Ctys.SelectedOrderType) @@ -1192,11 +1194,11 @@ bool Cty_GetDataOfCountryByCod (struct Country *Cty,Cty_GetExtraData_t GetExtraD extern const char *Txt_Another_country; extern const char *Txt_STR_LANG_ID[1+Txt_NUM_LANGUAGES]; char StrField[32]; - char SubQueryNam1[(1+Txt_NUM_LANGUAGES)*32]; - char SubQueryNam2[(1+Txt_NUM_LANGUAGES)*32]; - char SubQueryWWW1[(1+Txt_NUM_LANGUAGES)*32]; - char SubQueryWWW2[(1+Txt_NUM_LANGUAGES)*32]; - char Query[1024+(1+Txt_NUM_LANGUAGES)*32*4]; + char SubQueryNam1[Cty_MAX_LENGTH_SUBQUERY_CTYS + 1]; + char SubQueryNam2[Cty_MAX_LENGTH_SUBQUERY_CTYS + 1]; + char SubQueryWWW1[Cty_MAX_LENGTH_SUBQUERY_CTYS + 1]; + char SubQueryWWW2[Cty_MAX_LENGTH_SUBQUERY_CTYS + 1]; + char Query[1024 + Cty_MAX_LENGTH_SUBQUERY_CTYS * 4]; MYSQL_RES *mysql_res; MYSQL_ROW row; unsigned long NumRows; @@ -1255,14 +1257,14 @@ bool Cty_GetDataOfCountryByCod (struct Country *Cty,Cty_GetExtraData_t GetExtraD Lan++) { sprintf (StrField,"countries.Name_%s,",Txt_STR_LANG_ID[Lan]); - strcat (SubQueryNam1,StrField); + Str_Concat (SubQueryNam1,StrField,Cty_MAX_LENGTH_SUBQUERY_CTYS); sprintf (StrField,"Name_%s,",Txt_STR_LANG_ID[Lan]); - strcat (SubQueryNam2,StrField); + Str_Concat (SubQueryNam2,StrField,Cty_MAX_LENGTH_SUBQUERY_CTYS); sprintf (StrField,"countries.WWW_%s,",Txt_STR_LANG_ID[Lan]); - strcat (SubQueryWWW1,StrField); + Str_Concat (SubQueryWWW1,StrField,Cty_MAX_LENGTH_SUBQUERY_CTYS); sprintf (StrField,"WWW_%s,",Txt_STR_LANG_ID[Lan]); - strcat (SubQueryWWW2,StrField); + Str_Concat (SubQueryWWW2,StrField,Cty_MAX_LENGTH_SUBQUERY_CTYS); } sprintf (Query,"(SELECT countries.Alpha2,%s%sCOUNT(*) AS NumUsrs" " FROM countries,usr_data" @@ -2077,17 +2079,24 @@ void Cty_RecFormNewCountry (void) /**************************** Create a new country ***************************/ /*****************************************************************************/ +#define Cty_MAX_LENGTH_SUBQUERY_CTYS_NAME ((1 + Txt_NUM_LANGUAGES) * Cty_MAX_BYTES_COUNTRY_NAME) +#define Cty_MAX_LENGTH_SUBQUERY_CTYS_WWW ((1 + Txt_NUM_LANGUAGES) * Cns_MAX_LENGTH_WWW) + static void Cty_CreateCountry (struct Country *Cty) { extern const char *Txt_STR_LANG_ID[1+Txt_NUM_LANGUAGES]; extern const char *Txt_Created_new_country_X; Txt_Language_t Lan; char StrField[32]; - char SubQueryNam1[(1+Txt_NUM_LANGUAGES)*32]; - char SubQueryNam2[(1+Txt_NUM_LANGUAGES)*Cty_MAX_BYTES_COUNTRY_NAME]; - char SubQueryWWW1[(1+Txt_NUM_LANGUAGES)*32]; - char SubQueryWWW2[(1+Txt_NUM_LANGUAGES)*Cns_MAX_LENGTH_WWW]; - char Query[1024 + (1 + Txt_NUM_LANGUAGES) * (32 + Cty_MAX_BYTES_COUNTRY_NAME + 32 + Cns_MAX_LENGTH_WWW)]; + char SubQueryNam1[Cty_MAX_LENGTH_SUBQUERY_CTYS + 1]; + char SubQueryNam2[Cty_MAX_LENGTH_SUBQUERY_CTYS_NAME + 1]; + char SubQueryWWW1[Cty_MAX_LENGTH_SUBQUERY_CTYS + 1]; + char SubQueryWWW2[Cty_MAX_LENGTH_SUBQUERY_CTYS_WWW + 1]; + char Query[1024 + + Cty_MAX_LENGTH_SUBQUERY_CTYS + + Cty_MAX_LENGTH_SUBQUERY_CTYS_NAME + + Cty_MAX_LENGTH_SUBQUERY_CTYS + + Cty_MAX_LENGTH_SUBQUERY_CTYS_WWW]; /***** Create a new country *****/ SubQueryNam1[0] = '\0'; @@ -2099,18 +2108,18 @@ static void Cty_CreateCountry (struct Country *Cty) Lan++) { sprintf (StrField,",Name_%s",Txt_STR_LANG_ID[Lan]); - strcat (SubQueryNam1,StrField); + Str_Concat (SubQueryNam1,StrField,Cty_MAX_LENGTH_SUBQUERY_CTYS); - strcat (SubQueryNam2,",'"); - strcat (SubQueryNam2,Cty->Name[Lan]); - strcat (SubQueryNam2,"'"); + Str_Concat (SubQueryNam2,",'" ,Cty_MAX_LENGTH_SUBQUERY_CTYS_NAME); + Str_Concat (SubQueryNam2,Cty->Name[Lan],Cty_MAX_LENGTH_SUBQUERY_CTYS_NAME); + Str_Concat (SubQueryNam2,"'" ,Cty_MAX_LENGTH_SUBQUERY_CTYS_NAME); sprintf (StrField,",WWW_%s",Txt_STR_LANG_ID[Lan]); - strcat (SubQueryWWW1,StrField); + Str_Concat (SubQueryWWW1,StrField,Cty_MAX_LENGTH_SUBQUERY_CTYS); - strcat (SubQueryWWW2,",'"); - strcat (SubQueryWWW2,Cty->WWW[Lan]); - strcat (SubQueryWWW2,"'"); + Str_Concat (SubQueryWWW2,",'" ,Cty_MAX_LENGTH_SUBQUERY_CTYS_WWW); + Str_Concat (SubQueryWWW2,Cty->WWW[Lan],Cty_MAX_LENGTH_SUBQUERY_CTYS_WWW); + Str_Concat (SubQueryWWW2,"'" ,Cty_MAX_LENGTH_SUBQUERY_CTYS_WWW); } sprintf (Query,"INSERT INTO countries (CtyCod,Alpha2%s%s)" " VALUES ('%03ld','%s'%s%s)", diff --git a/swad_file.c b/swad_file.c index 7c9b975f..6a4257c3 100644 --- a/swad_file.c +++ b/swad_file.c @@ -318,13 +318,17 @@ bool Fil_EndReceptionOfFile (char *FileNameDataTmp,struct Param *Param) // OldName is created // NewName is created -void Fil_CreateUpdateFile (const char *CurrentName,const char *ExtensionOldName,char *OldName,char *NewName,FILE **NewFile) +void Fil_CreateUpdateFile (const char CurrentName[PATH_MAX + 1], + const char *ExtensionOldName, + char OldName[PATH_MAX + 1], + char NewName[PATH_MAX + 1], + FILE **NewFile) { size_t LengthFileRoot = Str_GetLengthRootFileName (CurrentName); Str_Copy (NewName,CurrentName,LengthFileRoot); sprintf (OldName,"%s%s",NewName,ExtensionOldName); - strcat (NewName,".new"); + Str_Concat (NewName,".new",PATH_MAX); /* The new file shouldn't exist. If it exists is due to any error when running this CGI formerly and the file was not renamed successfully. In this case, remove it! */ diff --git a/swad_file.h b/swad_file.h index def5409b..58a2e5d9 100644 --- a/swad_file.h +++ b/swad_file.h @@ -66,7 +66,11 @@ void Fil_EndOfReadingStdin (void); struct Param *Fil_StartReceptionOfFile (const char *ParamFile, char *FileName,char *MIMEType); bool Fil_EndReceptionOfFile (char *FileNameDataTmp,struct Param *Param); -void Fil_CreateUpdateFile (const char *CurrentName,const char *ExtensionOldName,char *OldName,char *NewName,FILE **NewFile); +void Fil_CreateUpdateFile (const char CurrentName[PATH_MAX + 1], + const char *ExtensionOldName, + char OldName[PATH_MAX + 1], + char NewName[PATH_MAX + 1], + FILE **NewFile); void Fil_CloseUpdateFile (const char *CurrentName,const char *OldName,const char *NewName,FILE *NewFile); bool Fil_RenameFileOrDir (const char *PathOld,const char *PathNew); diff --git a/swad_file_browser.c b/swad_file_browser.c index f05a1781..c758b1b3 100644 --- a/swad_file_browser.c +++ b/swad_file_browser.c @@ -8145,7 +8145,7 @@ void Brw_RecFolderFileBrowser (void) extern const char *Txt_Can_not_create_the_folder_X_because_there_is_already_a_folder_or_a_file_with_that_name; extern const char *Txt_The_folder_X_has_been_created_inside_the_folder_Y; extern const char *Txt_You_can_not_create_folders_here; - char Path[PATH_MAX+1]; + char Path[PATH_MAX + 1]; char PathCompleteInTreeIncludingFolder[PATH_MAX+1]; char FileNameToShow[NAME_MAX+1]; @@ -8162,8 +8162,8 @@ void Brw_RecFolderFileBrowser (void) if (strlen (Path) + 1 + strlen (Gbl.FileBrowser.NewFilFolLnkName) > PATH_MAX) Lay_ShowErrorAndExit ("Path is too long."); - strcat (Path,"/"); - strcat (Path,Gbl.FileBrowser.NewFilFolLnkName); + Str_Concat (Path,"/",PATH_MAX); + Str_Concat (Path,Gbl.FileBrowser.NewFilFolLnkName,PATH_MAX); /* Create the new directory */ if (mkdir (Path,(mode_t) 0xFFF) == 0) @@ -8391,8 +8391,8 @@ static bool Brw_RcvFileInFileBrw (Brw_UploadType_t UploadType) extern const char *Txt_UPLOAD_FILE_You_must_specify_the_file_NO_HTML; extern const char *Txt_UPLOAD_FILE_Forbidden_NO_HTML; struct Param *Param; - char SrcFileName[PATH_MAX+1]; - char PathUntilFileName[PATH_MAX+1]; + char SrcFileName[PATH_MAX + 1]; + char PathUntilFileName[PATH_MAX + 1]; char Path[PATH_MAX+1]; char PathTmp[PATH_MAX+1]; char PathCompleteInTreeIncludingFile[PATH_MAX + 1]; @@ -8436,8 +8436,8 @@ static bool Brw_RcvFileInFileBrw (Brw_UploadType_t UploadType) Gbl.FileBrowser.Priv.FullPathInTree); if (strlen (Path) + 1 + strlen (Gbl.FileBrowser.NewFilFolLnkName) + strlen (".tmp") > PATH_MAX) Lay_ShowErrorAndExit ("Path is too long."); - strcat (Path,"/"); - strcat (Path,Gbl.FileBrowser.NewFilFolLnkName); + Str_Concat (Path,"/",PATH_MAX); + Str_Concat (Path,Gbl.FileBrowser.NewFilFolLnkName,PATH_MAX); /* Check if the destination file exists */ if (Fil_CheckIfPathExists (Path)) @@ -8572,16 +8572,16 @@ void Brw_RecLinkFileBrowser (void) extern const char *Txt_The_link_X_has_been_placed_inside_the_folder_Y; extern const char *Txt_UPLOAD_FILE_Invalid_link; extern const char *Txt_You_can_not_create_links_here; - char URL[PATH_MAX+1]; - char URLWithoutEndingSlash[PATH_MAX+1]; + char URL[PATH_MAX + 1]; + char URLWithoutEndingSlash[PATH_MAX + 1]; size_t LengthURL; - char URLUntilLastFilename[PATH_MAX+1]; - char FileName[NAME_MAX+1]; - char Path[PATH_MAX+1]; + char URLUntilLastFilename[PATH_MAX + 1]; + char FileName[NAME_MAX + 1]; + char Path[PATH_MAX + 1]; FILE *FileURL; - char PathCompleteInTreeIncludingFile[PATH_MAX+1]; + char PathCompleteInTreeIncludingFile[PATH_MAX + 1]; long FilCod = -1L; // Code of new file in database - char FileNameToShow[NAME_MAX+1]; + char FileNameToShow[NAME_MAX + 1]; struct FileMetadata FileMetadata; unsigned NumUsrsToBeNotifiedByEMail; @@ -8629,9 +8629,9 @@ void Brw_RecLinkFileBrowser (void) sprintf (Path,"%s/%s",Gbl.FileBrowser.Priv.PathAboveRootFolder,Gbl.FileBrowser.Priv.FullPathInTree); if (strlen (Path) + 1 + strlen (FileName) + strlen (".url") > PATH_MAX) Lay_ShowErrorAndExit ("Path is too long."); - strcat (Path,"/"); - strcat (Path,FileName); - strcat (Path,".url"); + Str_Concat (Path,"/",PATH_MAX); + Str_Concat (Path,FileName,PATH_MAX); + Str_Concat (Path,".url",PATH_MAX); /* Check if the URL file exists */ if (Fil_CheckIfPathExists (Path)) diff --git a/swad_group.c b/swad_group.c index 0e756ef2..441387e6 100644 --- a/swad_group.c +++ b/swad_group.c @@ -3080,7 +3080,9 @@ void Grp_GetNamesGrpsStdBelongsTo (long GrpTypCod,long UsrCod,char *GroupNames) char Query[512]; MYSQL_RES *mysql_res; MYSQL_ROW row; - unsigned long NumRow,NumRows; + unsigned long NumRow; + unsigned long NumRows; + size_t MaxLength = (Grp_MAX_LENGTH_GROUP_NAME + 2) * Gbl.CurrentCrs.Grps.GrpTypes.NumGrpsTotal; /***** Get the names of groups which a user belongs to, from database *****/ sprintf (Query,"SELECT crs_grp.GrpName FROM crs_grp,crs_grp_usr" @@ -3102,8 +3104,8 @@ void Grp_GetNamesGrpsStdBelongsTo (long GrpTypCod,long UsrCod,char *GroupNames) /* El group name in row[0] */ if (NumRow) - strcat (GroupNames,", "); - strcat (GroupNames,row[0]); + Str_Concat (GroupNames,", ",MaxLength); + Str_Concat (GroupNames,row[0],MaxLength); } /***** Free structure that stores the query result *****/ @@ -4032,7 +4034,7 @@ void Grp_RenameGroup (void) extern const char *Txt_The_name_of_the_group_X_has_not_changed; struct GroupData GrpDat; char Query[512]; - char NewNameGrp[Grp_MAX_LENGTH_GROUP_NAME+1]; + char NewNameGrp[Grp_MAX_LENGTH_GROUP_NAME + 1]; /***** Get parameters from form *****/ /* Get the code of the group */ diff --git a/swad_mail.c b/swad_mail.c index 7fefa674..093800b0 100644 --- a/swad_mail.c +++ b/swad_mail.c @@ -838,7 +838,7 @@ void Mai_ListEmails (void) unsigned NumUsr; unsigned NumStdsWithEmail; unsigned NumAcceptedStdsWithEmail; - char StrAddresses[Mai_MAX_LENGTH_STR_ADDR+1]; + char StrAddresses[Mai_MAX_LENGTH_STR_ADDR + 1]; unsigned int LengthStrAddr = 0; struct UsrData UsrDat; @@ -884,18 +884,15 @@ void Mai_ListEmails (void) if (NumAcceptedStdsWithEmail > 0) { fprintf (Gbl.F.Out,", "); - LengthStrAddr += 2; - if (LengthStrAddr <= Mai_MAX_LENGTH_STR_ADDR) - strcat (StrAddresses,","); - else + LengthStrAddr ++; + if (LengthStrAddr > Mai_MAX_LENGTH_STR_ADDR) Lay_ShowErrorAndExit ("The space allocated to store email addresses is full."); + Str_Concat (StrAddresses,",",Mai_MAX_LENGTH_STR_ADDR); } LengthStrAddr += strlen (UsrDat.Email); - if (LengthStrAddr <= Mai_MAX_LENGTH_STR_ADDR) - strcat (StrAddresses,UsrDat.Email); - else + if (LengthStrAddr > Mai_MAX_LENGTH_STR_ADDR) Lay_ShowErrorAndExit ("The space allocated to store email addresses is full."); - + Str_Concat (StrAddresses,UsrDat.Email,Mai_MAX_LENGTH_STR_ADDR); fprintf (Gbl.F.Out,"%s", UsrDat.Email,Gbl.CurrentCrs.Crs.FullName,UsrDat.Email); @@ -1715,8 +1712,8 @@ void Mai_ConfirmEmail (void) " AND usr_emails.E_mail='%s'", UsrCod,Email); DB_QueryUPDATE (Query,"can not confirm email"); + sprintf (Gbl.Message,Txt_The_email_X_has_been_confirmed,Email); - strcat (Gbl.Message,"."); } Lay_ShowAlert (Lay_SUCCESS,Gbl.Message); } diff --git a/swad_message.c b/swad_message.c index 392d0657..7f742ca9 100644 --- a/swad_message.c +++ b/swad_message.c @@ -1052,7 +1052,7 @@ void Msg_GetParamFilterContent (void) static void Msg_MakeFilterFromToSubquery (char FilterFromToSubquery[Msg_MAX_LENGTH_MESSAGES_QUERY + 1]) { const char *Ptr; - char SearchWord[Usr_MAX_LENGTH_USR_NAME_OR_SURNAME+1]; + char SearchWord[Usr_MAX_LENGTH_USR_NAME_OR_SURNAME + 1]; /***** Split "from"/"to" string into words *****/ if (Gbl.Msg.FilterFromTo[0]) @@ -1066,10 +1066,10 @@ static void Msg_MakeFilterFromToSubquery (char FilterFromToSubquery[Msg_MAX_LENG Str_GetNextStringUntilSpace (&Ptr,SearchWord,Usr_MAX_LENGTH_USR_NAME_OR_SURNAME); if (strlen (FilterFromToSubquery) + strlen (SearchWord) + 512 > Msg_MAX_LENGTH_MESSAGES_QUERY) // Prevent string overflow break; - strcat (FilterFromToSubquery,"%"); - strcat (FilterFromToSubquery,SearchWord); + Str_Concat (FilterFromToSubquery,"%",Msg_MAX_LENGTH_MESSAGES_QUERY); + Str_Concat (FilterFromToSubquery,SearchWord,Msg_MAX_LENGTH_MESSAGES_QUERY); } - strcat (FilterFromToSubquery,"%'"); + Str_Concat (FilterFromToSubquery,"%'",Msg_MAX_LENGTH_MESSAGES_QUERY); } else FilterFromToSubquery[0] = '\0'; diff --git a/swad_photo.c b/swad_photo.c index d2a185c6..acbf208d 100644 --- a/swad_photo.c +++ b/swad_photo.c @@ -1167,12 +1167,12 @@ void Pho_ShowUsrPhoto (const struct UsrData *UsrDat,const char *PhotoURL, Str_Copy (Surnames,UsrDat->Surname1,Usr_MAX_BYTES_SURNAMES); if (UsrDat->Surname2[0]) { - strcat (Surnames," "); - strcat (Surnames,UsrDat->Surname2); + Str_Concat (Surnames," ",Usr_MAX_BYTES_SURNAMES); + Str_Concat (Surnames,UsrDat->Surname2,Usr_MAX_BYTES_SURNAMES); } Str_LimitLengthHTMLStr (Surnames,23); - strcat (ShortName,"
"); - strcat (ShortName,Surnames); + Str_Concat (ShortName,"
",Usr_MAX_BYTES_FULL_NAME); + Str_Concat (ShortName,Surnames,Usr_MAX_BYTES_FULL_NAME); Act_SetUniqueId (IdCaption); fprintf (Gbl.F.Out,"
" diff --git a/swad_record.c b/swad_record.c index ede63427..82ece8e2 100644 --- a/swad_record.c +++ b/swad_record.c @@ -630,12 +630,13 @@ void Rec_AskConfirmRemFieldWithRecords (unsigned NumRecords) sprintf (Gbl.Message,Txt_Do_you_really_want_to_remove_the_field_X_from_the_records_of_X, Gbl.CurrentCrs.Records.Field.Name,Gbl.CurrentCrs.Crs.FullName); if (NumRecords == 1) - strcat (Gbl.Message,Txt_this_field_is_filled_in_the_record_of_one_student); + Str_Concat (Gbl.Message,Txt_this_field_is_filled_in_the_record_of_one_student, + Lay_MAX_BYTES_ALERT); else { sprintf (Message_part2,Txt_this_field_is_filled_in_the_records_of_X_students, NumRecords); - strcat (Gbl.Message,Message_part2); + Str_Concat (Gbl.Message,Message_part2,Lay_MAX_BYTES_ALERT); } Lay_ShowAlert (Lay_WARNING,Gbl.Message); diff --git a/swad_search.c b/swad_search.c index 2e3cc91b..6911faaa 100644 --- a/swad_search.c +++ b/swad_search.c @@ -26,7 +26,7 @@ /*****************************************************************************/ #include // For fprintf... -#include // For strcat... +#include // For string functions... #include "swad_database.h" #include "swad_global.h" @@ -666,8 +666,8 @@ static void Sch_SearchInDB (void) static unsigned Sch_SearchInstitutionsInDB (const char *RangeQuery) { extern const char *Txt_STR_LANG_ID[1+Txt_NUM_LANGUAGES]; - char SearchQuery[Sch_MAX_LENGTH_SEARCH_QUERY+1]; - char Query[1024+Sch_MAX_LENGTH_SEARCH_QUERY*2]; + char SearchQuery[Sch_MAX_LENGTH_SEARCH_QUERY + 1]; + char Query[1024 + Sch_MAX_LENGTH_SEARCH_QUERY * 2]; /***** Check scope *****/ if (Gbl.Scope.Current != Sco_SCOPE_CTR && @@ -1219,7 +1219,8 @@ static unsigned Sch_SearchMyDocumentsInDB (const char *RangeQuery) // Returns true if a valid search query is built // Returns false when no valid search query -bool Sch_BuildSearchQuery (char *SearchQuery,const char *FieldName, +bool Sch_BuildSearchQuery (char SearchQuery[Sch_MAX_LENGTH_SEARCH_QUERY + 1], + const char *FieldName, const char *CharSet,const char *Collate) { const char *Ptr; @@ -1273,18 +1274,18 @@ bool Sch_BuildSearchQuery (char *SearchQuery,const char *FieldName, Sch_MAX_LENGTH_SEARCH_QUERY) // Prevent string overflow break; if (NumWords) - strcat (SearchQuery," AND "); - strcat (SearchQuery,FieldName); - strcat (SearchQuery," LIKE "); + Str_Concat (SearchQuery," AND ",Sch_MAX_LENGTH_SEARCH_QUERY); + Str_Concat (SearchQuery,FieldName,Sch_MAX_LENGTH_SEARCH_QUERY); + Str_Concat (SearchQuery," LIKE ",Sch_MAX_LENGTH_SEARCH_QUERY); if (CharSet) if (CharSet[0]) - strcat (SearchQuery,CharSet); - strcat (SearchQuery,"'%"); - strcat (SearchQuery,SearchWords[NumWords]); - strcat (SearchQuery,"%'"); + Str_Concat (SearchQuery,CharSet,Sch_MAX_LENGTH_SEARCH_QUERY); + Str_Concat (SearchQuery,"'%",Sch_MAX_LENGTH_SEARCH_QUERY); + Str_Concat (SearchQuery,SearchWords[NumWords],Sch_MAX_LENGTH_SEARCH_QUERY); + Str_Concat (SearchQuery,"%'",Sch_MAX_LENGTH_SEARCH_QUERY); if (Collate) if (Collate[0]) - strcat (SearchQuery,Collate); + Str_Concat (SearchQuery,Collate,Sch_MAX_LENGTH_SEARCH_QUERY); } } diff --git a/swad_search.h b/swad_search.h index 98d23204..561eaa1e 100644 --- a/swad_search.h +++ b/swad_search.h @@ -81,7 +81,8 @@ void Sch_CtrSearch (void); void Sch_DegSearch (void); void Sch_CrsSearch (void); -bool Sch_BuildSearchQuery (char *SearchQuery,const char *FieldName, +bool Sch_BuildSearchQuery (char SearchQuery[Sch_MAX_LENGTH_SEARCH_QUERY + 1], + const char *FieldName, const char *CharSet,const char *Collate); #endif diff --git a/swad_statistic.c b/swad_statistic.c index a98c91b4..a548cd49 100644 --- a/swad_statistic.c +++ b/swad_statistic.c @@ -264,10 +264,11 @@ void Sta_GetRemoteAddr (void) /**************************** Log access in database *************************/ /*****************************************************************************/ +#define Sta_MAX_LENGTH_QUERY_LOG (2048 - 1) void Sta_LogAccess (const char *Comments) { extern struct Act_Actions Act_Actions[Act_NUM_ACTIONS]; - char Query[2048]; + char Query[Sta_MAX_LENGTH_QUERY_LOG + 1]; long LogCod; Rol_Role_t RoleToStore = (Gbl.Action.Act == ActLogOut) ? Gbl.Usrs.Me.LoggedRoleBeforeCloseSession : Gbl.Usrs.Me.LoggedRole; @@ -333,7 +334,7 @@ void Sta_LogAccess (const char *Comments) " VALUES ('%ld','", LogCod); Str_AddStrToQuery (Query,Comments,sizeof (Query)); - strcat (Query,"')"); + Str_Concat (Query,"')",Sta_MAX_LENGTH_QUERY_LOG); if (Gbl.WebService.IsWebService) { @@ -804,7 +805,7 @@ void Sta_SeeCrsAccesses (void) /******************** Compute and show access statistics ********************/ /*****************************************************************************/ -#define Sta_MAX_LENGTH_QUERY_ACCESS (1024 + (10+ID_MAX_LENGTH_USR_ID)*5000) +#define Sta_MAX_LENGTH_QUERY_ACCESS (1024 + (10+ID_MAX_LENGTH_USR_ID)*5000 - 1) #define Sta_MAX_LENGTH_COUNT_TYPE (256 - 1) @@ -818,7 +819,7 @@ static void Sta_ShowHits (Sta_GlobalOrCourseAccesses_t GlobalOrCourse) extern const char *Txt_List_of_detailed_clicks; extern const char *Txt_STAT_TYPE_COUNT_CAPS[Sta_NUM_COUNT_TYPES]; extern const char *Txt_Time_zone_used_in_the_calculation_of_these_statistics; - char Query[Sta_MAX_LENGTH_QUERY_ACCESS+1]; + char Query[Sta_MAX_LENGTH_QUERY_ACCESS + 1]; char QueryAux[512]; long LengthQuery; MYSQL_RES *mysql_res; @@ -1110,7 +1111,7 @@ static void Sta_ShowHits (Sta_GlobalOrCourseAccesses_t GlobalOrCourse) LogTable, (long) Gbl.DateRange.TimeUTC[0], (long) Gbl.DateRange.TimeUTC[1]); - strcat (Query,QueryAux); + Str_Concat (Query,QueryAux,Sta_MAX_LENGTH_QUERY_ACCESS); switch (GlobalOrCourse) { @@ -1126,7 +1127,7 @@ static void Sta_ShowHits (Sta_GlobalOrCourseAccesses_t GlobalOrCourse) { sprintf (QueryAux," AND %s.CtyCod='%ld'", LogTable,Gbl.CurrentCty.Cty.CtyCod); - strcat (Query,QueryAux); + Str_Concat (Query,QueryAux,Sta_MAX_LENGTH_QUERY_ACCESS); } break; case Sco_SCOPE_INS: @@ -1134,7 +1135,7 @@ static void Sta_ShowHits (Sta_GlobalOrCourseAccesses_t GlobalOrCourse) { sprintf (QueryAux," AND %s.InsCod='%ld'", LogTable,Gbl.CurrentIns.Ins.InsCod); - strcat (Query,QueryAux); + Str_Concat (Query,QueryAux,Sta_MAX_LENGTH_QUERY_ACCESS); } break; case Sco_SCOPE_CTR: @@ -1142,7 +1143,7 @@ static void Sta_ShowHits (Sta_GlobalOrCourseAccesses_t GlobalOrCourse) { sprintf (QueryAux," AND %s.CtrCod='%ld'", LogTable,Gbl.CurrentCtr.Ctr.CtrCod); - strcat (Query,QueryAux); + Str_Concat (Query,QueryAux,Sta_MAX_LENGTH_QUERY_ACCESS); } break; case Sco_SCOPE_DEG: @@ -1150,7 +1151,7 @@ static void Sta_ShowHits (Sta_GlobalOrCourseAccesses_t GlobalOrCourse) { sprintf (QueryAux," AND %s.DegCod='%ld'", LogTable,Gbl.CurrentDeg.Deg.DegCod); - strcat (Query,QueryAux); + Str_Concat (Query,QueryAux,Sta_MAX_LENGTH_QUERY_ACCESS); } break; case Sco_SCOPE_CRS: @@ -1158,7 +1159,7 @@ static void Sta_ShowHits (Sta_GlobalOrCourseAccesses_t GlobalOrCourse) { sprintf (QueryAux," AND %s.CrsCod='%ld'", LogTable,Gbl.CurrentCrs.Crs.CrsCod); - strcat (Query,QueryAux); + Str_Concat (Query,QueryAux,Sta_MAX_LENGTH_QUERY_ACCESS); } break; } @@ -1222,7 +1223,7 @@ static void Sta_ShowHits (Sta_GlobalOrCourseAccesses_t GlobalOrCourse) LogTable,Gbl.Usrs.Me.UsrDat.UsrCod); break; } - strcat (Query,StrRole); + Str_Concat (Query,StrRole,Sta_MAX_LENGTH_QUERY_ACCESS); switch (Gbl.Stat.ClicksGroupedBy) { @@ -1230,12 +1231,12 @@ static void Sta_ShowHits (Sta_GlobalOrCourseAccesses_t GlobalOrCourse) case Sta_CLICKS_GBL_PER_WEB_SERVICE_FUNCTION: sprintf (QueryAux," AND %s.LogCod=log_ws.LogCod", LogTable); - strcat (Query,QueryAux); + Str_Concat (Query,QueryAux,Sta_MAX_LENGTH_QUERY_ACCESS); break; case Sta_CLICKS_GBL_PER_BANNER: sprintf (QueryAux," AND %s.LogCod=log_banners.LogCod", LogTable); - strcat (Query,QueryAux); + Str_Concat (Query,QueryAux,Sta_MAX_LENGTH_QUERY_ACCESS); break; default: break; @@ -1244,7 +1245,7 @@ static void Sta_ShowHits (Sta_GlobalOrCourseAccesses_t GlobalOrCourse) case Sta_SHOW_COURSE_ACCESSES: sprintf (QueryAux," AND %s.CrsCod='%ld'", LogTable,Gbl.CurrentCrs.Crs.CrsCod); - strcat (Query,QueryAux); + Str_Concat (Query,QueryAux,Sta_MAX_LENGTH_QUERY_ACCESS); LengthQuery = strlen (Query); NumUsr = 0; Ptr = Gbl.Usrs.Select.All; @@ -1261,11 +1262,11 @@ static void Sta_ShowHits (Sta_GlobalOrCourseAccesses_t GlobalOrCourse) NumUsr ? " OR %s.UsrCod='%ld'" : " AND (%s.UsrCod='%ld'", LogTable,UsrDat.UsrCod); - strcat (Query,QueryAux); + Str_Concat (Query,QueryAux,Sta_MAX_LENGTH_QUERY_ACCESS); NumUsr++; } } - strcat (Query,")"); + Str_Concat (Query,")",Sta_MAX_LENGTH_QUERY_ACCESS); break; } @@ -1274,76 +1275,79 @@ static void Sta_ShowHits (Sta_GlobalOrCourseAccesses_t GlobalOrCourse) { sprintf (QueryAux," AND %s.ActCod='%ld'", LogTable,Act_Actions[Gbl.Stat.NumAction].ActCod); - strcat (Query,QueryAux); + Str_Concat (Query,QueryAux,Sta_MAX_LENGTH_QUERY_ACCESS); } /* End the query */ switch (Gbl.Stat.ClicksGroupedBy) { case Sta_CLICKS_CRS_DETAILED_LIST: - strcat (Query," ORDER BY F"); + Str_Concat (Query," ORDER BY F",Sta_MAX_LENGTH_QUERY_ACCESS); break; case Sta_CLICKS_CRS_PER_USR: sprintf (QueryAux," GROUP BY %s.UsrCod ORDER BY Num DESC",LogTable); - strcat (Query,QueryAux); + Str_Concat (Query,QueryAux,Sta_MAX_LENGTH_QUERY_ACCESS); break; case Sta_CLICKS_CRS_PER_DAYS: case Sta_CLICKS_GBL_PER_DAYS: - strcat (Query," GROUP BY Day DESC"); + Str_Concat (Query," GROUP BY Day DESC",Sta_MAX_LENGTH_QUERY_ACCESS); break; case Sta_CLICKS_CRS_PER_DAYS_AND_HOUR: case Sta_CLICKS_GBL_PER_DAYS_AND_HOUR: - strcat (Query," GROUP BY Day DESC,Hour"); + Str_Concat (Query," GROUP BY Day DESC,Hour",Sta_MAX_LENGTH_QUERY_ACCESS); break; case Sta_CLICKS_CRS_PER_WEEKS: case Sta_CLICKS_GBL_PER_WEEKS: - strcat (Query," GROUP BY Week DESC"); + Str_Concat (Query," GROUP BY Week DESC",Sta_MAX_LENGTH_QUERY_ACCESS); break; case Sta_CLICKS_CRS_PER_MONTHS: case Sta_CLICKS_GBL_PER_MONTHS: - strcat (Query," GROUP BY Month DESC"); + Str_Concat (Query," GROUP BY Month DESC",Sta_MAX_LENGTH_QUERY_ACCESS); break; case Sta_CLICKS_CRS_PER_HOUR: case Sta_CLICKS_GBL_PER_HOUR: - strcat (Query," GROUP BY Hour"); + Str_Concat (Query," GROUP BY Hour",Sta_MAX_LENGTH_QUERY_ACCESS); break; case Sta_CLICKS_CRS_PER_MINUTE: case Sta_CLICKS_GBL_PER_MINUTE: - strcat (Query," GROUP BY Minute"); + Str_Concat (Query," GROUP BY Minute",Sta_MAX_LENGTH_QUERY_ACCESS); break; case Sta_CLICKS_CRS_PER_ACTION: case Sta_CLICKS_GBL_PER_ACTION: sprintf (QueryAux," GROUP BY %s.ActCod ORDER BY Num DESC",LogTable); - strcat (Query,QueryAux); + Str_Concat (Query,QueryAux,Sta_MAX_LENGTH_QUERY_ACCESS); break; case Sta_CLICKS_GBL_PER_PLUGIN: - strcat (Query," GROUP BY log_ws.PlgCod ORDER BY Num DESC"); + Str_Concat (Query," GROUP BY log_ws.PlgCod ORDER BY Num DESC", + Sta_MAX_LENGTH_QUERY_ACCESS); break; case Sta_CLICKS_GBL_PER_WEB_SERVICE_FUNCTION: - strcat (Query," GROUP BY log_ws.FunCod ORDER BY Num DESC"); + Str_Concat (Query," GROUP BY log_ws.FunCod ORDER BY Num DESC", + Sta_MAX_LENGTH_QUERY_ACCESS); break; case Sta_CLICKS_GBL_PER_BANNER: - strcat (Query," GROUP BY log_banners.BanCod ORDER BY Num DESC"); + Str_Concat (Query," GROUP BY log_banners.BanCod ORDER BY Num DESC", + Sta_MAX_LENGTH_QUERY_ACCESS); break; case Sta_CLICKS_GBL_PER_COUNTRY: sprintf (QueryAux," GROUP BY %s.CtyCod ORDER BY Num DESC",LogTable); - strcat (Query,QueryAux); + Str_Concat (Query,QueryAux,Sta_MAX_LENGTH_QUERY_ACCESS); break; case Sta_CLICKS_GBL_PER_INSTITUTION: sprintf (QueryAux," GROUP BY %s.InsCod ORDER BY Num DESC",LogTable); - strcat (Query,QueryAux); + Str_Concat (Query,QueryAux,Sta_MAX_LENGTH_QUERY_ACCESS); break; case Sta_CLICKS_GBL_PER_CENTRE: sprintf (QueryAux," GROUP BY %s.CtrCod ORDER BY Num DESC",LogTable); - strcat (Query,QueryAux); + Str_Concat (Query,QueryAux,Sta_MAX_LENGTH_QUERY_ACCESS); break; case Sta_CLICKS_GBL_PER_DEGREE: sprintf (QueryAux," GROUP BY %s.DegCod ORDER BY Num DESC",LogTable); - strcat (Query,QueryAux); + Str_Concat (Query,QueryAux,Sta_MAX_LENGTH_QUERY_ACCESS); break; case Sta_CLICKS_GBL_PER_COURSE: sprintf (QueryAux," GROUP BY %s.CrsCod ORDER BY Num DESC",LogTable); - strcat (Query,QueryAux); + Str_Concat (Query,QueryAux,Sta_MAX_LENGTH_QUERY_ACCESS); break; } /***** Write query for debug *****/ diff --git a/swad_string.c b/swad_string.c index 12e1fad1..1a555b32 100644 --- a/swad_string.c +++ b/swad_string.c @@ -1102,13 +1102,15 @@ void Str_ChangeFormat (Str_ChangeFrom_t ChangeFrom,Str_ChangeTo_t ChangeTo, // Insert a space to separate former string from   // This space is not printed on screen in HTML, // but it is necessary to mark the end of a possible previous URL - strcat (StrSpecialChar, - ThereIsSpaceChar ? " " : - " "); // The first space + Str_Concat (StrSpecialChar, + ThereIsSpaceChar ? " " : + " ", // The first space + Str_MAX_LENGTH_SPECIAL_CHAR); for (i = 1; i < NumSpacesTab; i++) // Rest of spaces, except the first - strcat (StrSpecialChar," "); // Add a space + Str_Concat (StrSpecialChar," ", // Add a space + Str_MAX_LENGTH_SPECIAL_CHAR); NumPrintableCharsFromReturn += NumSpacesTab; } else diff --git a/swad_survey.c b/swad_survey.c index eb4e35f6..263a00b1 100644 --- a/swad_survey.c +++ b/swad_survey.c @@ -694,8 +694,8 @@ static void Svy_WriteAuthor (struct Survey *Svy) Str_Copy (Surnames,UsrDat.Surname1,Usr_MAX_BYTES_SURNAMES); if (UsrDat.Surname2[0]) { - strcat (Surnames," "); - strcat (Surnames,UsrDat.Surname2); + Str_Concat (Surnames," ",Usr_MAX_BYTES_SURNAMES); + Str_Concat (Surnames,UsrDat.Surname2,Usr_MAX_BYTES_SURNAMES); } Str_LimitLengthHTMLStr (FirstName,8); Str_LimitLengthHTMLStr (Surnames,8); diff --git a/swad_syllabus.c b/swad_syllabus.c index 25d42060..361b077d 100644 --- a/swad_syllabus.c +++ b/swad_syllabus.c @@ -30,7 +30,7 @@ #include // For NULL #include // For SOAP_OK and soap functions #include // For free () -#include // For strcat (), etc. +#include // For string functions #include // For time () #include "swad_changelog.h" @@ -52,6 +52,9 @@ extern struct Globals Gbl; /*****************************************************************************/ #define Syl_MAX_LEVELS_SYLLABUS 10 + +#define Syl_MAX_LENGTH_ITEM_COD (Syl_MAX_LEVELS_SYLLABUS * (10 + 1) - 1) + #define Syl_MAX_LENGTH_TEXT_ITEM 1024 #define Syl_MAX_BYTES_TEXT_ITEM (Syl_MAX_LENGTH_TEXT_ITEM*Str_MAX_CHARACTER) @@ -107,6 +110,8 @@ static void Syl_ShowRowSyllabus (unsigned NumItem, static void Syl_WriteSyllabusIntoHTMLTmpFile (FILE *FileHTMLTmp); static void Syl_PutFormItemSyllabus (bool NewItem,unsigned NumItem,int Level,int *CodItem,const char *Text); +static void Syl_WriteNumItem (char *StrDst,FILE *FileTgt,int Level,int *CodItem); + /*****************************************************************************/ /******************** Get parameter to select a syllabus *********************/ /*****************************************************************************/ @@ -573,7 +578,7 @@ static void Syl_ShowRowSyllabus (unsigned NumItem, extern const char *Txt_Increase_level_of_X; extern const char *Txt_Decrease_level_of_X; static int LastLevel = 0; - char StrItemCod[Syl_MAX_LEVELS_SYLLABUS*(10+1)]; + char StrItemCod[Syl_MAX_LEVELS_SYLLABUS * (10 + 1)]; struct MoveSubtrees Subtree; Subtree.ToGetUp.Ini = Subtree.ToGetUp.End = 0; @@ -969,7 +974,7 @@ void Syl_PutParamNumItem (unsigned NumItem) /******************** Write number of item in legal style ********************/ /*****************************************************************************/ -void Syl_WriteNumItem (char *StrDst,FILE *FileTgt,int Level,int *CodItem) +static void Syl_WriteNumItem (char *StrDst,FILE *FileTgt,int Level,int *CodItem) { int N; char InStr[1+10+1]; @@ -984,13 +989,13 @@ void Syl_WriteNumItem (char *StrDst,FILE *FileTgt,int Level,int *CodItem) if (N > 1) { if (StrDst) - strcat (StrDst,"."); + Str_Concat (StrDst,".",Syl_MAX_LENGTH_ITEM_COD); if (FileTgt) fprintf (FileTgt,"."); } sprintf (InStr,"%d",CodItem[N]); if (StrDst) - strcat (StrDst,InStr); + Str_Concat (StrDst,InStr,Syl_MAX_LENGTH_ITEM_COD); if (FileTgt) fprintf (FileTgt,"%s",InStr); } @@ -1002,9 +1007,9 @@ void Syl_WriteNumItem (char *StrDst,FILE *FileTgt,int Level,int *CodItem) void Syl_RemoveItemSyllabus (void) { - char PathFile[PATH_MAX+1]; - char PathOldFile[PATH_MAX+1]; - char PathNewFile[PATH_MAX+1]; + char PathFile[PATH_MAX + 1]; + char PathOldFile[PATH_MAX + 1]; + char PathNewFile[PATH_MAX + 1]; FILE *NewFile; unsigned NumItem; diff --git a/swad_syllabus.h b/swad_syllabus.h index bb8dd5f4..0f4b9c69 100644 --- a/swad_syllabus.h +++ b/swad_syllabus.h @@ -80,7 +80,7 @@ void Syl_FreeListItemsSyllabus (void); int Syl_ReadLevelItemSyllabus (void); int Syl_WriteSyllabusIntoHTMLBuffer (char **HTMLBuffer); void Syl_PutParamNumItem (unsigned NumItem); -void Syl_WriteNumItem (char *StrDst,FILE *FileTgt,int Level,int *CodItem); + void Syl_RemoveItemSyllabus (void); void Syl_UpItemSyllabus (void); void Syl_DownItemSyllabus (void); diff --git a/swad_test.c b/swad_test.c index 1cb0abab..14f139a9 100644 --- a/swad_test.c +++ b/swad_test.c @@ -2344,17 +2344,17 @@ void Tst_ListQuestionsToEdit (void) /********** Get from the database several test questions for listing *********/ /*****************************************************************************/ -#define MAX_LENGTH_QUERY_TEST (16*1024) +#define Tst_MAX_LENGTH_QUERY_TEST (16*1024 - 1) static unsigned long Tst_GetQuestionsForEdit (MYSQL_RES **mysql_res) { extern const char *Txt_No_questions_found_matching_your_search_criteria; unsigned long NumRows; - char Query[MAX_LENGTH_QUERY_TEST+1]; + char Query[Tst_MAX_LENGTH_QUERY_TEST + 1]; long LengthQuery; unsigned NumItemInList; const char *Ptr; - char TagText[Tst_MAX_BYTES_TAG+1]; + char TagText[Tst_MAX_BYTES_TAG + 1]; char LongStr[1+10+1]; char UnsignedStr[10+1]; Tst_AnswerType_t AnsType; @@ -2387,27 +2387,27 @@ static unsigned long Tst_GetQuestionsForEdit (MYSQL_RES **mysql_res) "tst_questions.Score" " FROM tst_questions"); if (!Gbl.Test.Tags.All) - strcat (Query,",tst_question_tags,tst_tags"); + Str_Concat (Query,",tst_question_tags,tst_tags",Tst_MAX_LENGTH_QUERY_TEST); - strcat (Query," WHERE tst_questions.CrsCod='"); + Str_Concat (Query," WHERE tst_questions.CrsCod='",Tst_MAX_LENGTH_QUERY_TEST); sprintf (CrsCodStr,"%ld",Gbl.CurrentCrs.Crs.CrsCod); - strcat (Query,CrsCodStr); - strcat (Query,"' AND tst_questions.EditTime>=FROM_UNIXTIME('"); + Str_Concat (Query,CrsCodStr,Tst_MAX_LENGTH_QUERY_TEST); + Str_Concat (Query,"' AND tst_questions.EditTime>=FROM_UNIXTIME('",Tst_MAX_LENGTH_QUERY_TEST); sprintf (LongStr,"%ld",(long) Gbl.DateRange.TimeUTC[0]); - strcat (Query,LongStr); - strcat (Query,"') AND tst_questions.EditTime<=FROM_UNIXTIME('"); + Str_Concat (Query,LongStr,Tst_MAX_LENGTH_QUERY_TEST); + Str_Concat (Query,"') AND tst_questions.EditTime<=FROM_UNIXTIME('",Tst_MAX_LENGTH_QUERY_TEST); sprintf (LongStr,"%ld",(long) Gbl.DateRange.TimeUTC[1]); - strcat (Query,LongStr); - strcat (Query,"')"); + Str_Concat (Query,LongStr,Tst_MAX_LENGTH_QUERY_TEST); + Str_Concat (Query,"')",Tst_MAX_LENGTH_QUERY_TEST); /* Add the tags selected */ if (!Gbl.Test.Tags.All) { - strcat (Query," AND tst_questions.QstCod=tst_question_tags.QstCod" - " AND tst_question_tags.TagCod=tst_tags.TagCod" - " AND tst_tags.CrsCod='"); - strcat (Query,CrsCodStr); - strcat (Query,"'"); + Str_Concat (Query," AND tst_questions.QstCod=tst_question_tags.QstCod" + " AND tst_question_tags.TagCod=tst_tags.TagCod" + " AND tst_tags.CrsCod='",Tst_MAX_LENGTH_QUERY_TEST); + Str_Concat (Query,CrsCodStr,Tst_MAX_LENGTH_QUERY_TEST); + Str_Concat (Query,"'",Tst_MAX_LENGTH_QUERY_TEST); LengthQuery = strlen (Query); NumItemInList = 0; Ptr = Gbl.Test.Tags.List; @@ -2415,16 +2415,17 @@ static unsigned long Tst_GetQuestionsForEdit (MYSQL_RES **mysql_res) { Par_GetNextStrUntilSeparParamMult (&Ptr,TagText,Tst_MAX_BYTES_TAG); LengthQuery = LengthQuery + 35 + strlen (TagText) + 1; - if (LengthQuery > MAX_LENGTH_QUERY_TEST - 256) + if (LengthQuery > Tst_MAX_LENGTH_QUERY_TEST - 256) Lay_ShowErrorAndExit ("Query size exceed."); - strcat (Query, - NumItemInList ? " OR tst_tags.TagTxt='" : - " AND (tst_tags.TagTxt='"); - strcat (Query,TagText); - strcat (Query,"'"); + Str_Concat (Query, + NumItemInList ? " OR tst_tags.TagTxt='" : + " AND (tst_tags.TagTxt='", + Tst_MAX_LENGTH_QUERY_TEST); + Str_Concat (Query,TagText,Tst_MAX_LENGTH_QUERY_TEST); + Str_Concat (Query,"'",Tst_MAX_LENGTH_QUERY_TEST); NumItemInList++; } - strcat (Query,")"); + Str_Concat (Query,")",Tst_MAX_LENGTH_QUERY_TEST); } /* Add the types of answer selected */ @@ -2438,43 +2439,44 @@ static unsigned long Tst_GetQuestionsForEdit (MYSQL_RES **mysql_res) Par_GetNextStrUntilSeparParamMult (&Ptr,UnsignedStr,Tst_MAX_BYTES_TAG); AnsType = Tst_ConvertFromUnsignedStrToAnsTyp (UnsignedStr); LengthQuery = LengthQuery + 35 + strlen (Tst_StrAnswerTypesDB[AnsType]) + 1; - if (LengthQuery > MAX_LENGTH_QUERY_TEST - 256) + if (LengthQuery > Tst_MAX_LENGTH_QUERY_TEST - 256) Lay_ShowErrorAndExit ("Query size exceed."); - strcat (Query, - NumItemInList ? " OR tst_questions.AnsType='" : - " AND (tst_questions.AnsType='"); - strcat (Query,Tst_StrAnswerTypesDB[AnsType]); - strcat (Query,"'"); + Str_Concat (Query, + NumItemInList ? " OR tst_questions.AnsType='" : + " AND (tst_questions.AnsType='", + Tst_MAX_LENGTH_QUERY_TEST); + Str_Concat (Query,Tst_StrAnswerTypesDB[AnsType],Tst_MAX_LENGTH_QUERY_TEST); + Str_Concat (Query,"'",Tst_MAX_LENGTH_QUERY_TEST); NumItemInList++; } - strcat (Query,")"); + Str_Concat (Query,")",Tst_MAX_LENGTH_QUERY_TEST); } /* End the query */ - strcat (Query," GROUP BY tst_questions.QstCod"); + Str_Concat (Query," GROUP BY tst_questions.QstCod",Tst_MAX_LENGTH_QUERY_TEST); switch (Gbl.Test.SelectedOrderType) { case Tst_ORDER_STEM: - strcat (Query," ORDER BY tst_questions.Stem"); + Str_Concat (Query," ORDER BY tst_questions.Stem",Tst_MAX_LENGTH_QUERY_TEST); break; case Tst_ORDER_NUM_HITS: - strcat (Query," ORDER BY tst_questions.NumHits DESC," - "tst_questions.Stem"); + Str_Concat (Query," ORDER BY tst_questions.NumHits DESC," + "tst_questions.Stem",Tst_MAX_LENGTH_QUERY_TEST); break; case Tst_ORDER_AVERAGE_SCORE: - strcat (Query," ORDER BY tst_questions.Score/tst_questions.NumHits DESC," - "tst_questions.NumHits DESC," - "tst_questions.Stem"); + Str_Concat (Query," ORDER BY tst_questions.Score/tst_questions.NumHits DESC," + "tst_questions.NumHits DESC," + "tst_questions.Stem",Tst_MAX_LENGTH_QUERY_TEST); break; case Tst_ORDER_NUM_HITS_NOT_BLANK: - strcat (Query," ORDER BY tst_questions.NumHitsNotBlank DESC," - "tst_questions.Stem"); + Str_Concat (Query," ORDER BY tst_questions.NumHitsNotBlank DESC," + "tst_questions.Stem",Tst_MAX_LENGTH_QUERY_TEST); break; case Tst_ORDER_AVERAGE_SCORE_NOT_BLANK: - strcat (Query," ORDER BY tst_questions.Score/tst_questions.NumHitsNotBlank DESC," - "tst_questions.NumHitsNotBlank DESC," - "tst_questions.Stem"); + Str_Concat (Query," ORDER BY tst_questions.Score/tst_questions.NumHitsNotBlank DESC," + "tst_questions.NumHitsNotBlank DESC," + "tst_questions.Stem",Tst_MAX_LENGTH_QUERY_TEST); break; } @@ -2493,7 +2495,7 @@ static unsigned long Tst_GetQuestionsForEdit (MYSQL_RES **mysql_res) static unsigned long Tst_GetQuestionsForTest (MYSQL_RES **mysql_res) { - char Query[MAX_LENGTH_QUERY_TEST+1]; + char Query[Tst_MAX_LENGTH_QUERY_TEST + 1]; long LengthQuery; unsigned NumItemInList; const char *Ptr; @@ -2554,16 +2556,17 @@ static unsigned long Tst_GetQuestionsForTest (MYSQL_RES **mysql_res) { Par_GetNextStrUntilSeparParamMult (&Ptr,TagText,Tst_MAX_BYTES_TAG); LengthQuery = LengthQuery + 35 + strlen (TagText) + 1; - if (LengthQuery > MAX_LENGTH_QUERY_TEST - 128) + if (LengthQuery > Tst_MAX_LENGTH_QUERY_TEST - 128) Lay_ShowErrorAndExit ("Query size exceed."); - strcat (Query, - NumItemInList ? " OR tst_tags.TagTxt='" : - " AND (tst_tags.TagTxt='"); - strcat (Query,TagText); - strcat (Query,"'"); + Str_Concat (Query, + NumItemInList ? " OR tst_tags.TagTxt='" : + " AND (tst_tags.TagTxt='", + Tst_MAX_LENGTH_QUERY_TEST); + Str_Concat (Query,TagText,Tst_MAX_LENGTH_QUERY_TEST); + Str_Concat (Query,"'",Tst_MAX_LENGTH_QUERY_TEST); NumItemInList++; } - strcat (Query,")"); + Str_Concat (Query,")",Tst_MAX_LENGTH_QUERY_TEST); } /* Add answer types selected */ @@ -2577,22 +2580,23 @@ static unsigned long Tst_GetQuestionsForTest (MYSQL_RES **mysql_res) Par_GetNextStrUntilSeparParamMult (&Ptr,UnsignedStr,Tst_MAX_BYTES_TAG); AnsType = Tst_ConvertFromUnsignedStrToAnsTyp (UnsignedStr); LengthQuery = LengthQuery + 35 + strlen (Tst_StrAnswerTypesDB[AnsType]) + 1; - if (LengthQuery > MAX_LENGTH_QUERY_TEST - 128) + if (LengthQuery > Tst_MAX_LENGTH_QUERY_TEST - 128) Lay_ShowErrorAndExit ("Query size exceed."); - strcat (Query, - NumItemInList ? " OR tst_questions.AnsType='" : - " AND (tst_questions.AnsType='"); - strcat (Query,Tst_StrAnswerTypesDB[AnsType]); - strcat (Query,"'"); + Str_Concat (Query, + NumItemInList ? " OR tst_questions.AnsType='" : + " AND (tst_questions.AnsType='", + Tst_MAX_LENGTH_QUERY_TEST); + Str_Concat (Query,Tst_StrAnswerTypesDB[AnsType],Tst_MAX_LENGTH_QUERY_TEST); + Str_Concat (Query,"'",Tst_MAX_LENGTH_QUERY_TEST); NumItemInList++; } - strcat (Query,")"); + Str_Concat (Query,")",Tst_MAX_LENGTH_QUERY_TEST); } /* End query */ - strcat (Query," ORDER BY RAND(NOW()) LIMIT "); + Str_Concat (Query," ORDER BY RAND(NOW()) LIMIT ",Tst_MAX_LENGTH_QUERY_TEST); sprintf (StrNumQsts,"%u",Gbl.Test.NumQsts); - strcat (Query,StrNumQsts); + Str_Concat (Query,StrNumQsts,Tst_MAX_LENGTH_QUERY_TEST); /* if (Gbl.Usrs.Me.LoggedRole == Rol_SYS_ADM) Lay_ShowAlert (Lay_INFO,Query); diff --git a/swad_user.c b/swad_user.c index d87525ce..3a3ae099 100644 --- a/swad_user.c +++ b/swad_user.c @@ -94,6 +94,8 @@ const char *Usr_IconsClassPhotoOrList[Usr_NUM_USR_LIST_TYPES] = #define Usr_NUM_ALL_FIELDS_DATA_TCH 11 const char *Usr_UsrDatMainFieldNames[Usr_NUM_MAIN_FIELDS_DATA_USR]; +#define Usr_MAX_LENGTH_QUERY_GET_LIST_USRS (16*1024 - 1) + /*****************************************************************************/ /****************************** Internal types *******************************/ /*****************************************************************************/ @@ -144,7 +146,8 @@ static void Usr_WriteUsrData (const char *BgColor, const char *Data,const char *Link, bool NonBreak,bool Accepted); -static void Usr_BuildQueryToGetUsrsLstCrs (Rol_Role_t Role,char *Query); +static void Usr_BuildQueryToGetUsrsLstCrs (Rol_Role_t Role, + char Query[Usr_MAX_LENGTH_QUERY_GET_LIST_USRS + 1]); static void Usr_GetAdmsLst (Sco_Scope_t Scope); static void Usr_GetGstsLst (Sco_Scope_t Scope); @@ -704,13 +707,13 @@ void Usr_BuildFullName (struct UsrData *UsrDat) Str_Copy (UsrDat->FullName,UsrDat->FirstName,Usr_MAX_BYTES_FULL_NAME); if (UsrDat->Surname1[0]) { - strcat (UsrDat->FullName," "); - strcat (UsrDat->FullName,UsrDat->Surname1); + Str_Concat (UsrDat->FullName," ",Usr_MAX_BYTES_FULL_NAME); + Str_Concat (UsrDat->FullName,UsrDat->Surname1,Usr_MAX_BYTES_FULL_NAME); } if (UsrDat->Surname2[0]) { - strcat (UsrDat->FullName," "); - strcat (UsrDat->FullName,UsrDat->Surname2); + Str_Concat (UsrDat->FullName," ",Usr_MAX_BYTES_FULL_NAME); + Str_Concat (UsrDat->FullName,UsrDat->Surname2,Usr_MAX_BYTES_FULL_NAME); } } @@ -725,13 +728,14 @@ void Usr_RestrictLengthAndWriteName (const struct UsrData *UsrDat,unsigned MaxCh /***** Restrict length of firstname and surnames *****/ Str_Copy (FirstName,UsrDat->FirstName,Usr_MAX_BYTES_NAME); + Str_LimitLengthHTMLStr (FirstName,MaxChars); + Str_Copy (Surnames,UsrDat->Surname1,Usr_MAX_BYTES_SURNAMES); if (UsrDat->Surname2[0]) { - strcat (Surnames," "); - strcat (Surnames,UsrDat->Surname2); + Str_Concat (Surnames," ",Usr_MAX_BYTES_SURNAMES); + Str_Concat (Surnames,UsrDat->Surname2,Usr_MAX_BYTES_SURNAMES); } - Str_LimitLengthHTMLStr (FirstName,MaxChars); Str_LimitLengthHTMLStr (Surnames,MaxChars); /***** Write shorted firstname, then return, then shorted surnames *****/ @@ -3229,7 +3233,8 @@ static void Usr_WriteRowStdAllData (struct UsrData *UsrDat,char *GroupNames) NumGrpTyp++) if (Gbl.CurrentCrs.Grps.GrpTypes.LstGrpTypes[NumGrpTyp].NumGrps) // If current course tiene groups of este type { - Grp_GetNamesGrpsStdBelongsTo (Gbl.CurrentCrs.Grps.GrpTypes.LstGrpTypes[NumGrpTyp].GrpTypCod,UsrDat->UsrCod,GroupNames); + Grp_GetNamesGrpsStdBelongsTo (Gbl.CurrentCrs.Grps.GrpTypes.LstGrpTypes[NumGrpTyp].GrpTypCod, + UsrDat->UsrCod,GroupNames); Usr_WriteUsrData (Gbl.ColorRows[Gbl.RowEvenOdd],GroupNames,NULL,true,UsrDat->Accepted); } @@ -3753,7 +3758,8 @@ unsigned Usr_GetNumberOfTeachersInCentre (long CtrCod) /******* Build query to get list with data of users in current course ********/ /*****************************************************************************/ -static void Usr_BuildQueryToGetUsrsLstCrs (Rol_Role_t Role,char *Query) +static void Usr_BuildQueryToGetUsrsLstCrs (Rol_Role_t Role, + char Query[Usr_MAX_LENGTH_QUERY_GET_LIST_USRS + 1]) { unsigned NumPositiveCods = 0; unsigned NumNegativeCods = 0; @@ -3854,22 +3860,24 @@ static void Usr_BuildQueryToGetUsrsLstCrs (Rol_Role_t Role,char *Query) /* If there are positive codes, add the students who belong to groups with those codes */ if (NumPositiveCods) { - strcat (Query," AND (crs_usr.UsrCod IN" - " (SELECT DISTINCT UsrCod FROM crs_grp_usr WHERE"); + Str_Concat (Query," AND (crs_usr.UsrCod IN" + " (SELECT DISTINCT UsrCod FROM crs_grp_usr WHERE", + Usr_MAX_LENGTH_QUERY_GET_LIST_USRS); NumPositiveCods = 0; for (NumGrpSel = 0; NumGrpSel < Gbl.CurrentCrs.Grps.LstGrpsSel.NumGrps; NumGrpSel++) if ((GrpCod = Gbl.CurrentCrs.Grps.LstGrpsSel.GrpCod[NumGrpSel]) > 0) { - strcat (Query,NumPositiveCods ? " OR GrpCod='" : - " GrpCod='"); + Str_Concat (Query,NumPositiveCods ? " OR GrpCod='" : + " GrpCod='", + Usr_MAX_LENGTH_QUERY_GET_LIST_USRS); sprintf (LongStr,"%ld",GrpCod); - strcat (Query,LongStr); - strcat (Query,"'"); + Str_Concat (Query,LongStr,Usr_MAX_LENGTH_QUERY_GET_LIST_USRS); + Str_Concat (Query,"'",Usr_MAX_LENGTH_QUERY_GET_LIST_USRS); NumPositiveCods++; } - strcat (Query,")"); + Str_Concat (Query,")",Usr_MAX_LENGTH_QUERY_GET_LIST_USRS); } } @@ -3880,22 +3888,24 @@ static void Usr_BuildQueryToGetUsrsLstCrs (Rol_Role_t Role,char *Query) if (AddStdsWithoutGroupOf[NumGrpTyp]) { if (NumPositiveCods || NumNegativeCods) - strcat (Query," OR "); + Str_Concat (Query," OR ",Usr_MAX_LENGTH_QUERY_GET_LIST_USRS); else - strcat (Query," AND ("); + Str_Concat (Query," AND (",Usr_MAX_LENGTH_QUERY_GET_LIST_USRS); /* Select all the students of the course who don't belong to any group of type GrpTypCod */ - strcat (Query,"crs_usr.UsrCod NOT IN" - " (SELECT DISTINCT crs_grp_usr.UsrCod" - " FROM crs_grp,crs_grp_usr" - " WHERE crs_grp.GrpTypCod='"); + Str_Concat (Query,"crs_usr.UsrCod NOT IN" + " (SELECT DISTINCT crs_grp_usr.UsrCod" + " FROM crs_grp,crs_grp_usr" + " WHERE crs_grp.GrpTypCod='", + Usr_MAX_LENGTH_QUERY_GET_LIST_USRS); sprintf (LongStr,"%ld",Gbl.CurrentCrs.Grps.GrpTypes.LstGrpTypes[NumGrpTyp].GrpTypCod); - strcat (Query,LongStr); - strcat (Query,"' AND crs_grp.GrpCod=crs_grp_usr.GrpCod)"); + Str_Concat (Query,LongStr,Usr_MAX_LENGTH_QUERY_GET_LIST_USRS); + Str_Concat (Query,"' AND crs_grp.GrpCod=crs_grp_usr.GrpCod)", + Usr_MAX_LENGTH_QUERY_GET_LIST_USRS); NumNegativeCods++; } if (NumPositiveCods || NumNegativeCods) - strcat (Query,")"); + Str_Concat (Query,")",Usr_MAX_LENGTH_QUERY_GET_LIST_USRS); /***** Free memory used by the list of booleans AddStdsWithoutGroupOf *****/ free ((void *) AddStdsWithoutGroupOf); @@ -3905,11 +3915,11 @@ static void Usr_BuildQueryToGetUsrsLstCrs (Rol_Role_t Role,char *Query) } /***** The last part of the query is for ordering the list *****/ - strcat (Query," ORDER BY " - "usr_data.Surname1," - "usr_data.Surname2," - "usr_data.FirstName," - "usr_data.UsrCod"); + Str_Concat (Query," ORDER BY " + "usr_data.Surname1," + "usr_data.Surname2," + "usr_data.FirstName," + "usr_data.UsrCod",Usr_MAX_LENGTH_QUERY_GET_LIST_USRS); } /*****************************************************************************/ @@ -3921,8 +3931,7 @@ static void Usr_BuildQueryToGetUsrsLstCrs (Rol_Role_t Role,char *Query) void Usr_GetListUsrs (Rol_Role_t Role,Sco_Scope_t Scope) { - char Query[16*1024]; // Big query when the course has lot of groups - // TODO: Check buffer overflow when writing query + char Query[Usr_MAX_LENGTH_QUERY_GET_LIST_USRS + 1]; // Big query when the course has lot of groups const char *QueryFields = "DISTINCT usr_data.UsrCod," "usr_data.EncryptedUsrCod," @@ -5128,7 +5137,8 @@ bool Usr_GetListMsgRecipientsWrittenExplicitelyBySender (bool WriteErrorMsgs) { // Add another user Gbl.Usrs.Select.All[LengthSelectedUsrsCods] = Par_SEPARATOR_PARAM_MULTIPLE; - strcat (Gbl.Usrs.Select.All,UsrDat.EncryptedUsrCod); + Str_Concat (Gbl.Usrs.Select.All,UsrDat.EncryptedUsrCod, + Usr_MAX_BYTES_LIST_ENCRYPTED_USR_CODS); LengthSelectedUsrsCods += 1 + LengthUsrCod; } } @@ -5930,6 +5940,7 @@ void Usr_ListAllDataStds (void) unsigned NumGrpTyp,NumField; struct UsrData UsrDat; const char *FieldNames[Usr_NUM_ALL_FIELDS_DATA_STD]; + size_t Length; /***** Initialize field names *****/ FieldNames[ 0] = Txt_Photo; @@ -5989,8 +6000,11 @@ void Usr_ListAllDataStds (void) /***** Allocate memory for the string with the list of group names where student belongs to *****/ if (Gbl.Scope.Current == Sco_SCOPE_CRS) - if ((GroupNames = (char *) malloc ((Grp_MAX_LENGTH_GROUP_NAME+3)*Gbl.CurrentCrs.Grps.GrpTypes.NumGrpsTotal)) == NULL) + { + Length = (Grp_MAX_LENGTH_GROUP_NAME + 2) * Gbl.CurrentCrs.Grps.GrpTypes.NumGrpsTotal; + if ((GroupNames = (char *) malloc (Length + 1)) == NULL) Lay_ShowErrorAndExit ("Not enough memory to store names of groups."); + } /***** Start table with list of students *****/ fprintf (Gbl.F.Out,""); diff --git a/swad_web_service.c b/swad_web_service.c index f158c978..060d3916 100644 --- a/swad_web_service.c +++ b/swad_web_service.c @@ -2201,6 +2201,7 @@ static void Svc_GetListGrpsInAttendanceEventFromDB (long AttCod,char **ListGroup long NumGrp; long GrpCod; char GrpCodStr[10+1]; + size_t Length; /***** Get list of groups *****/ sprintf (Query,"SELECT GrpCod FROM att_grp WHERE AttCod='%ld'", @@ -2209,7 +2210,8 @@ static void Svc_GetListGrpsInAttendanceEventFromDB (long AttCod,char **ListGroup *ListGroups = NULL; else // Events found { - *ListGroups = soap_malloc (Gbl.soap,NumGrps * 10); + Length = NumGrps * (10 + 1) - 1; + *ListGroups = soap_malloc (Gbl.soap,Length + 1); for (NumGrp = 0; NumGrp < NumGrps; @@ -2224,7 +2226,7 @@ static void Svc_GetListGrpsInAttendanceEventFromDB (long AttCod,char **ListGroup NumGrp ? ",%ld" : "%ld", GrpCod); - strcat (*ListGroups,GrpCodStr); + Str_Concat (*ListGroups,GrpCodStr,Length); } } @@ -2638,6 +2640,7 @@ int swad__sendAttendanceUsers (struct soap *soap, long UsrCod; unsigned NumCodsInList; char SubQuery[256]; + size_t Length = 0; // Initialized to avoid warning char *Query = NULL; // Initialized to avoid warning /***** Initializations *****/ @@ -2686,7 +2689,8 @@ int swad__sendAttendanceUsers (struct soap *soap, Str_GetNextStringUntilComma (&Ptr,LongStr,1+10); /* Start query used to mark not present users as absent */ - if ((Query = (char *) malloc (256 + NumCodsInList * (1+1+10+1))) == NULL) + Length = 256 + NumCodsInList * (1+1+10+1) - 1; + if ((Query = (char *) malloc (Length + 1)) == NULL) return soap_receiver_fault (Gbl.soap, "Not enough memory", "Not enough memory to store list of users"); @@ -2718,7 +2722,7 @@ int swad__sendAttendanceUsers (struct soap *soap, sprintf (SubQuery,sendAttendanceUsersOut->numUsers ? ",'%ld'" : " AND UsrCod NOT IN ('%ld'", UsrCod); - strcat (Query,SubQuery); + Str_Concat (Query,SubQuery,Length); } sendAttendanceUsersOut->numUsers++; @@ -2729,7 +2733,7 @@ int swad__sendAttendanceUsers (struct soap *soap, { /* Mark not present users as absent in table of users */ if (sendAttendanceUsersOut->numUsers) - strcat (Query,")"); + Str_Concat (Query,")",Length); DB_QueryUPDATE (Query,"can not set other users as absent"); free ((void *) Query); @@ -3085,7 +3089,7 @@ int swad__markNotificationsAsRead (struct soap *soap, /****************** Send a message to one or more users **********************/ /*****************************************************************************/ -#define Svc_MAX_LENGHT_QUERY_RECIPIENTS (10*1024) +#define Svc_MAX_LENGTH_QUERY_RECIPIENTS (10*1024 - 1) int swad__sendMessage (struct soap *soap, char *wsKey,int messageCode,char *to,char *subject,char *body, // input @@ -3094,7 +3098,7 @@ int swad__sendMessage (struct soap *soap, int ReturnCode; long ReplyUsrCod = -1L; char Nickname[Nck_MAX_BYTES_NICKNAME_WITH_ARROBA+1]; - char Query[Svc_MAX_LENGHT_QUERY_RECIPIENTS+1]; + char Query[Svc_MAX_LENGTH_QUERY_RECIPIENTS + 1]; MYSQL_RES *mysql_res; MYSQL_ROW row; unsigned NumRow,NumRows; @@ -3199,7 +3203,7 @@ int swad__sendMessage (struct soap *soap, Str_RemoveLeadingArrobas (Nickname); /* Check for overflow in query */ - if (strlen (Query)+Nck_MAX_LENGTH_NICKNAME_WITHOUT_ARROBA+32 > Svc_MAX_LENGHT_QUERY_RECIPIENTS) + if (strlen (Query)+Nck_MAX_LENGTH_NICKNAME_WITHOUT_ARROBA+32 > Svc_MAX_LENGTH_QUERY_RECIPIENTS) return soap_sender_fault (Gbl.soap, "Can not send message", "Too many recipients"); @@ -3208,20 +3212,21 @@ int swad__sendMessage (struct soap *soap, if (FirstNickname) { if (ReplyUsrCod > 0) - strcat (Query," UNION "); - strcat (Query,"SELECT UsrCod FROM usr_nicknames" - " WHERE Nickname IN ('"); + Str_Concat (Query," UNION ",Svc_MAX_LENGTH_QUERY_RECIPIENTS); + Str_Concat (Query,"SELECT UsrCod FROM usr_nicknames" + " WHERE Nickname IN ('", + Svc_MAX_LENGTH_QUERY_RECIPIENTS); FirstNickname = false; ThereAreNicknames = true; } else - strcat (Query,",'"); - strcat (Query,Nickname); - strcat (Query,"'"); + Str_Concat (Query,",'",Svc_MAX_LENGTH_QUERY_RECIPIENTS); + Str_Concat (Query,Nickname,Svc_MAX_LENGTH_QUERY_RECIPIENTS); + Str_Concat (Query,"'",Svc_MAX_LENGTH_QUERY_RECIPIENTS); } } if (ThereAreNicknames) - strcat (Query,")"); + Str_Concat (Query,")",Svc_MAX_LENGTH_QUERY_RECIPIENTS); /***** Initialize output structure *****/ sendMessageOut->numUsers = 0; @@ -3932,6 +3937,8 @@ static int Svc_GetTstQuestionTags (long CrsCod,long BeginTime,struct swad__getTe /***************** Return one test question for Trivial game *****************/ /*****************************************************************************/ +#define Svc_MAX_LENGTH_DEGREES_STR (1024 - 1) + int swad__getTrivialQuestion (struct soap *soap, char *wsKey,char *degrees,float lowerScore,float upperScore, // input struct swad__getTrivialQuestionOutput *getTrivialQuestionOut) // output @@ -3940,7 +3947,7 @@ int swad__getTrivialQuestion (struct soap *soap, int ReturnCode; const char *Ptr; char LongStr[1+10+1]; - char DegreesStr[1024]; + char DegreesStr[Svc_MAX_LENGTH_DEGREES_STR + 1]; char DegStr[ 1+1+1+ 10 +1+ 1]; // DegStr=", ' - number ' \0" long DegCod; @@ -4004,7 +4011,7 @@ int swad__getTrivialQuestion (struct soap *soap, else { sprintf (DegStr,",'%ld'",DegCod); - strcat (DegreesStr,DegStr); + Str_Concat (DegreesStr,DegStr,Svc_MAX_LENGTH_DEGREES_STR); } } } diff --git a/swad_zip.c b/swad_zip.c index 23f39168..88199355 100644 --- a/swad_zip.c +++ b/swad_zip.c @@ -301,21 +301,21 @@ static void ZIP_CreateDirCompressionUsr (struct UsrData *UsrDat) Str_Copy (FullNameAndUsrID,UsrDat->Surname1,ZIP_MAX_LENGTH_FULL_NAME_AND_ID); if (UsrDat->Surname1[0] && UsrDat->Surname2[0]) - strcat (FullNameAndUsrID,"_"); // Separation between surname 1 and surname 2 - strcat (FullNameAndUsrID,UsrDat->Surname2); + Str_Concat (FullNameAndUsrID,"_",ZIP_MAX_LENGTH_FULL_NAME_AND_ID); // Separation between surname 1 and surname 2 + Str_Concat (FullNameAndUsrID,UsrDat->Surname2,ZIP_MAX_LENGTH_FULL_NAME_AND_ID); if ((UsrDat->Surname1[0] || UsrDat->Surname2[0]) && UsrDat->FirstName[0]) - strcat (FullNameAndUsrID,"_"); // Separation between surnames and first name - strcat (FullNameAndUsrID,UsrDat->FirstName); + Str_Concat (FullNameAndUsrID,"_",ZIP_MAX_LENGTH_FULL_NAME_AND_ID); // Separation between surnames and first name + Str_Concat (FullNameAndUsrID,UsrDat->FirstName,ZIP_MAX_LENGTH_FULL_NAME_AND_ID); if ((UsrDat->Surname1[0] || UsrDat->Surname2[0] || UsrDat->FirstName[0]) && UsrDat->IDs.Num) - strcat (FullNameAndUsrID,"-"); // Separation between name and ID + Str_Concat (FullNameAndUsrID,"-",ZIP_MAX_LENGTH_FULL_NAME_AND_ID); // Separation between name and ID Str_LimitLengthHTMLStr (FullNameAndUsrID,50); if (UsrDat->IDs.Num) // If this user has at least one ID - strcat (FullNameAndUsrID,UsrDat->IDs.List[0].ID); // First user's ID + Str_Concat (FullNameAndUsrID,UsrDat->IDs.List[0].ID,ZIP_MAX_LENGTH_FULL_NAME_AND_ID); // First user's ID Str_ConvertToValidFileName (FullNameAndUsrID); /* Create path to folder and link */