From 5ca28260fdfb377aab8e58b694fa6fd4ffa43a29 Mon Sep 17 00:00:00 2001 From: acanas Date: Tue, 18 Oct 2022 08:41:54 +0200 Subject: [PATCH] Version 22.49.3: Oct 18, 2022 Code refactoring related to parameters. --- swad_changelog.h | 3 +- swad_form.c | 30 ++++----- swad_form.h | 4 +- swad_global.h | 3 - swad_parameter.c | 38 ++++++++++-- swad_parameter.h | 2 + swad_string.c | 157 ++++++++++++++++++++++++----------------------- 7 files changed, 134 insertions(+), 103 deletions(-) diff --git a/swad_changelog.h b/swad_changelog.h index 358c0d09..5a9698c0 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -606,10 +606,11 @@ TODO: Fix bug: error al enviar un mensaje a dos recipientes, error on duplicate TODO: Attach pdf files in multimedia. */ -#define Log_PLATFORM_VERSION "SWAD 22.49.2 (2022-10-18)" +#define Log_PLATFORM_VERSION "SWAD 22.49.3 (2022-10-18)" #define CSS_FILE "swad22.49.css" #define JS_FILE "swad22.49.js" /* + Version 22.49.3: Oct 18, 2022 Code refactoring related to parameters. (333213 lines) Version 22.49.2: Oct 18, 2022 Code refactoring related to forms. (333189 lines) Version 22.49.1: Oct 17, 2022 Fixed bug filtering projects. (333176 lines) Version 22.49: Oct 16, 2022 Changes in project review form. (333161 lines) diff --git a/swad_form.c b/swad_form.c index 3cb569c3..59af58df 100644 --- a/swad_form.c +++ b/swad_form.c @@ -51,10 +51,24 @@ static bool Frm_Inside = false; /**************************** Private prototypes *****************************/ /*****************************************************************************/ +static inline void Frm_SetInside (bool Inside); + static void Frm_BeginFormInternal (Act_Action_t NextAction,bool PutParameterLocationIfNoSesion, const char *Id,const char *Anchor,const char *OnSubmit); -static inline void Frm_SetInside (bool Inside); +/*****************************************************************************/ +/************** Set to true inside a form to avoid nested forms **************/ +/*****************************************************************************/ + +static inline void Frm_SetInside (bool Inside) + { + Frm_Inside = Inside; + } + +bool Frm_CheckIfInside (void) + { + return Frm_Inside; + } /*****************************************************************************/ /******************************** Begin a form *******************************/ @@ -307,17 +321,3 @@ void Frm_LabelColumn (const char *TDClass,const char *Id,const char *Label) /***** Column/cell end *****/ HTM_TD_End (); } - -/*****************************************************************************/ -/************** Set to true inside a form to avoid nested forms **************/ -/*****************************************************************************/ - -static inline void Frm_SetInside (bool Inside) - { - Frm_Inside = Inside; - } - -bool Frm_CheckIfInside (void) - { - return Frm_Inside; - } diff --git a/swad_form.h b/swad_form.h index 8a6b6b85..b0d81679 100644 --- a/swad_form.h +++ b/swad_form.h @@ -46,6 +46,8 @@ /***************************** Public prototypes *****************************/ /*****************************************************************************/ +bool Frm_CheckIfInside (void); + void Frm_BeginFormGoTo (Act_Action_t NextAction); void Frm_BeginForm (Act_Action_t NextAction); void Frm_BeginFormOnSubmit (Act_Action_t NextAction,const char *OnSubmit); @@ -64,6 +66,4 @@ void Frm_FreeAnchorStr (char *Anchor); void Frm_LabelColumn (const char *TDClass,const char *Id,const char *Label); -bool Frm_CheckIfInside (void); - #endif diff --git a/swad_global.h b/swad_global.h index 49a173b3..a4d3b157 100644 --- a/swad_global.h +++ b/swad_global.h @@ -98,9 +98,6 @@ struct Globals bool GetMethod; // Am I accessing using GET method? } Params; - Act_Content_t ContentReceivedByCGI; /* Content send by the form and received by the CGI: - Act_CONTENT_NORM (if CONTENT_TYPE==text/plain) or - Act_CONT_DATA (if CONTENT_TYPE==multipart/form-data) */ struct { char StrWithoutCRLF[Par_MAX_BYTES_BOUNDARY_WITHOUT_CR_LF + 1]; diff --git a/swad_parameter.c b/swad_parameter.c index 17db26c4..3a87b15d 100644 --- a/swad_parameter.c +++ b/swad_parameter.c @@ -53,10 +53,22 @@ extern struct Globals Gbl; const char *Par_SEPARATOR_PARAM_MULTIPLE = "\x0a"; // Must be 1 <= character <= 31 +/*****************************************************************************/ +/************************* Private global variables **************************/ +/*****************************************************************************/ + +/* Content send by the form and received by the CGI: + Act_CONTENT_NORM (if CONTENT_TYPE==text/plain) + Act_CONT_DATA (if CONTENT_TYPE==multipart/form-data) +*/ +static Act_Content_t Par_ContentReceivedByCGI = Act_CONT_NORM; + /*****************************************************************************/ /***************************** Private prototypes ****************************/ /*****************************************************************************/ +static inline void Par_SetContentReceivedByCGI (Act_Content_t ContentReceivedByCGI); + static void Par_GetBoundary (void); static void Par_CreateListOfParamsFromQueryString (void); @@ -66,6 +78,20 @@ static int Par_ReadTmpFileUntilReturn (void); static bool Par_CheckIsParamCanBeUsedInGETMethod (const char *ParamName); +/*****************************************************************************/ +/********************** Type of content received by CGI **********************/ +/*****************************************************************************/ + +static inline void Par_SetContentReceivedByCGI (Act_Content_t ContentReceivedByCGI) + { + Par_ContentReceivedByCGI = ContentReceivedByCGI; + } + +Act_Content_t Par_GetContentReceivedByCGI (void) + { + return Par_ContentReceivedByCGI; + } + /*****************************************************************************/ /*** Read all parameters passed to this CGI and store for later processing ***/ /*****************************************************************************/ @@ -86,7 +112,7 @@ bool Par_GetQueryString (void) { /***** GET method *****/ Gbl.Params.GetMethod = true; - Gbl.ContentReceivedByCGI = Act_CONT_NORM; + Par_SetContentReceivedByCGI (Act_CONT_NORM); /* Get content length */ Gbl.Params.ContentLength = strlen (getenv ("QUERY_STRING")); @@ -124,7 +150,7 @@ bool Par_GetQueryString (void) if (!strncmp (ContentType,"multipart/form-data",strlen ("multipart/form-data"))) { - Gbl.ContentReceivedByCGI = Act_CONT_DATA; + Par_SetContentReceivedByCGI (Act_CONT_DATA); Par_GetBoundary (); return Fil_ReadStdinIntoTmpFile (); } @@ -134,7 +160,7 @@ bool Par_GetQueryString (void) } else { - Gbl.ContentReceivedByCGI = Act_CONT_NORM; + Par_SetContentReceivedByCGI (Act_CONT_NORM); /* Allocate memory for query string */ if ((Gbl.Params.QueryString = malloc (Gbl.Params.ContentLength + 1)) == NULL) @@ -225,7 +251,7 @@ void Par_CreateListOfParams (void) /***** Get list *****/ if (Gbl.Params.ContentLength) - CreateListOfParams[Gbl.ContentReceivedByCGI] (); + CreateListOfParams[Par_GetContentReceivedByCGI ()] (); } /*****************************************************************************/ @@ -518,7 +544,7 @@ unsigned Par_GetParameter (tParamType ParamType,const char *ParamName, { // The current element in the list has the length of the searched parameter // Check if the name of the parameter is the same - switch (Gbl.ContentReceivedByCGI) + switch (Par_GetContentReceivedByCGI ()) { case Act_CONT_NORM: ParamFound = !strncmp (ParamName,&Gbl.Params.QueryString[Param->Name.Start], @@ -580,7 +606,7 @@ unsigned Par_GetParameter (tParamType ParamType,const char *ParamName, } /* Copy parameter value */ - switch (Gbl.ContentReceivedByCGI) + switch (Par_GetContentReceivedByCGI ()) { case Act_CONT_NORM: if (PtrDst) diff --git a/swad_parameter.h b/swad_parameter.h index 2ac14681..d9e154bc 100644 --- a/swad_parameter.h +++ b/swad_parameter.h @@ -63,6 +63,8 @@ typedef enum /***************************** Public prototypes *****************************/ /*****************************************************************************/ +Act_Content_t Par_GetContentReceivedByCGI (void); + bool Par_GetQueryString (void); void Par_CreateListOfParams (void); void Par_FreeParams (void); diff --git a/swad_string.c b/swad_string.c index 408b0109..8c9a2067 100644 --- a/swad_string.c +++ b/swad_string.c @@ -753,88 +753,93 @@ void Str_ChangeFormat (Str_ChangeFrom_t ChangeFrom,Str_ChangeTo_t ChangeTo, switch (ChangeFrom) { case Str_FROM_FORM: - if (Gbl.ContentReceivedByCGI == Act_CONT_DATA) - // The form contained data and was sent with content type multipart/form-data - switch (Ch) - { - case 0x20: /* Space */ - case 0x22: /* Change double comilla --> """ */ - case 0x23: /* '#' */ - case 0x26: /* Change '&' --> "&" */ - case 0x27: /* Change single comilla --> "'" to avoid SQL code injection */ - case 0x2C: /* ',' */ - case 0x2F: /* '/' */ - case 0x3A: /* ':' */ - case 0x3B: /* ';' */ - case 0x3C: /* '<' --> "<" */ - case 0x3E: /* '>' --> ">" */ - case 0x3F: /* '?' */ - case 0x40: /* '@' */ - case 0x5C: /* '\\' */ - IsSpecialChar = true; - LengthSpecStrSrc = 1; - SpecialChar = (unsigned int) Ch; - break; - default: - if (Ch < 0x20 || Ch > 0x7F) - { + switch (Par_GetContentReceivedByCGI ()) + { + case Act_CONT_NORM: + // The form contained text and was sent with content type application/x-www-form-urlencoded + switch (Ch) + { + case '+': /* Change every '+' to a space */ + IsSpecialChar = true; + LengthSpecStrSrc = 1; + SpecialChar = 0x20; + break; + case '%': /* Change "%XX" --> "&#decimal_number;" (from 0 to 255) */ + /* Change "%uXXXX" --> "&#decimal number; (from 0 to 65535) */ + IsSpecialChar = true; + if (*(PtrSrc + 1) == 'u') + { + sscanf (PtrSrc + 2,"%4X",&SpecialChar); + LengthSpecStrSrc = 6; + } + else + { + sscanf (PtrSrc + 1,"%2X",&SpecialChar); + LengthSpecStrSrc = 3; + } + /* Some special characters, like a chinese character, + can be received from a form in a format like this: + %26%2335753%3B --> %26 %23 3 5 7 5 3 %3B --> 让 + ^ ^ ^ + | | | + SpecialChar SpecialChar SpecialChar + Here one chinese character is converted + to 2 special chars + 5 normal chars + 1 special char, + and finally is stored as the following 8 bytes: 让 + */ + break; + case 0x27: /* Change single comilla --> "'" to avoid SQL code injection */ + case 0x5C: /* '\\' */ IsSpecialChar = true; LengthSpecStrSrc = 1; SpecialChar = (unsigned int) Ch; - } - else - { + break; + default: IsSpecialChar = false; NumPrintableCharsFromReturn++; ThereIsSpaceChar = false; - } - break; - } - else // Gbl.ContentReceivedByCGI == Act_CONTENT_NORM - // The form contained text and was sent with content type application/x-www-form-urlencoded - switch (Ch) - { - case '+': /* Change every '+' to a space */ - IsSpecialChar = true; - LengthSpecStrSrc = 1; - SpecialChar = 0x20; - break; - case '%': /* Change "%XX" --> "&#decimal_number;" (from 0 to 255) */ - /* Change "%uXXXX" --> "&#decimal number; (from 0 to 65535) */ - IsSpecialChar = true; - if (*(PtrSrc + 1) == 'u') - { - sscanf (PtrSrc + 2,"%4X",&SpecialChar); - LengthSpecStrSrc = 6; - } - else - { - sscanf (PtrSrc + 1,"%2X",&SpecialChar); - LengthSpecStrSrc = 3; - } - /* Some special characters, like a chinese character, - can be received from a form in a format like this: - %26%2335753%3B --> %26 %23 3 5 7 5 3 %3B --> 让 - ^ ^ ^ - | | | - SpecialChar SpecialChar SpecialChar - Here one chinese character is converted - to 2 special chars + 5 normal chars + 1 special char, - and finally is stored as the following 8 bytes: 让 - */ - break; - case 0x27: /* Change single comilla --> "'" to avoid SQL code injection */ - case 0x5C: /* '\\' */ - IsSpecialChar = true; - LengthSpecStrSrc = 1; - SpecialChar = (unsigned int) Ch; - break; - default: - IsSpecialChar = false; - NumPrintableCharsFromReturn++; - ThereIsSpaceChar = false; - break; - } + break; + } + break; + case Act_CONT_DATA: + // The form contained data and was sent with content type multipart/form-data + switch (Ch) + { + case 0x20: /* Space */ + case 0x22: /* Change double comilla --> """ */ + case 0x23: /* '#' */ + case 0x26: /* Change '&' --> "&" */ + case 0x27: /* Change single comilla --> "'" to avoid SQL code injection */ + case 0x2C: /* ',' */ + case 0x2F: /* '/' */ + case 0x3A: /* ':' */ + case 0x3B: /* ';' */ + case 0x3C: /* '<' --> "<" */ + case 0x3E: /* '>' --> ">" */ + case 0x3F: /* '?' */ + case 0x40: /* '@' */ + case 0x5C: /* '\\' */ + IsSpecialChar = true; + LengthSpecStrSrc = 1; + SpecialChar = (unsigned int) Ch; + break; + default: + if (Ch < 0x20 || Ch > 0x7F) + { + IsSpecialChar = true; + LengthSpecStrSrc = 1; + SpecialChar = (unsigned int) Ch; + } + else + { + IsSpecialChar = false; + NumPrintableCharsFromReturn++; + ThereIsSpaceChar = false; + } + break; + } + break; + } break; case Str_FROM_HTML: case Str_FROM_TEXT: