Version 22.49.3: Oct 18, 2022 Code refactoring related to parameters.

This commit is contained in:
acanas 2022-10-18 08:41:54 +02:00
parent 2349e67e1b
commit 5ca28260fd
7 changed files with 134 additions and 103 deletions

View File

@ -606,10 +606,11 @@ TODO: Fix bug: error al enviar un mensaje a dos recipientes, error on duplicate
TODO: Attach pdf files in multimedia. 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 CSS_FILE "swad22.49.css"
#define JS_FILE "swad22.49.js" #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.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.1: Oct 17, 2022 Fixed bug filtering projects. (333176 lines)
Version 22.49: Oct 16, 2022 Changes in project review form. (333161 lines) Version 22.49: Oct 16, 2022 Changes in project review form. (333161 lines)

View File

@ -51,10 +51,24 @@ static bool Frm_Inside = false;
/**************************** Private prototypes *****************************/ /**************************** Private prototypes *****************************/
/*****************************************************************************/ /*****************************************************************************/
static inline void Frm_SetInside (bool Inside);
static void Frm_BeginFormInternal (Act_Action_t NextAction,bool PutParameterLocationIfNoSesion, static void Frm_BeginFormInternal (Act_Action_t NextAction,bool PutParameterLocationIfNoSesion,
const char *Id,const char *Anchor,const char *OnSubmit); 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 *******************************/ /******************************** Begin a form *******************************/
@ -307,17 +321,3 @@ void Frm_LabelColumn (const char *TDClass,const char *Id,const char *Label)
/***** Column/cell end *****/ /***** Column/cell end *****/
HTM_TD_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;
}

View File

@ -46,6 +46,8 @@
/***************************** Public prototypes *****************************/ /***************************** Public prototypes *****************************/
/*****************************************************************************/ /*****************************************************************************/
bool Frm_CheckIfInside (void);
void Frm_BeginFormGoTo (Act_Action_t NextAction); void Frm_BeginFormGoTo (Act_Action_t NextAction);
void Frm_BeginForm (Act_Action_t NextAction); void Frm_BeginForm (Act_Action_t NextAction);
void Frm_BeginFormOnSubmit (Act_Action_t NextAction,const char *OnSubmit); 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); void Frm_LabelColumn (const char *TDClass,const char *Id,const char *Label);
bool Frm_CheckIfInside (void);
#endif #endif

View File

@ -98,9 +98,6 @@ struct Globals
bool GetMethod; // Am I accessing using GET method? bool GetMethod; // Am I accessing using GET method?
} Params; } 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 struct
{ {
char StrWithoutCRLF[Par_MAX_BYTES_BOUNDARY_WITHOUT_CR_LF + 1]; char StrWithoutCRLF[Par_MAX_BYTES_BOUNDARY_WITHOUT_CR_LF + 1];

View File

@ -53,10 +53,22 @@ extern struct Globals Gbl;
const char *Par_SEPARATOR_PARAM_MULTIPLE = "\x0a"; // Must be 1 <= character <= 31 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 ****************************/ /***************************** Private prototypes ****************************/
/*****************************************************************************/ /*****************************************************************************/
static inline void Par_SetContentReceivedByCGI (Act_Content_t ContentReceivedByCGI);
static void Par_GetBoundary (void); static void Par_GetBoundary (void);
static void Par_CreateListOfParamsFromQueryString (void); static void Par_CreateListOfParamsFromQueryString (void);
@ -66,6 +78,20 @@ static int Par_ReadTmpFileUntilReturn (void);
static bool Par_CheckIsParamCanBeUsedInGETMethod (const char *ParamName); 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 ***/ /*** Read all parameters passed to this CGI and store for later processing ***/
/*****************************************************************************/ /*****************************************************************************/
@ -86,7 +112,7 @@ bool Par_GetQueryString (void)
{ {
/***** GET method *****/ /***** GET method *****/
Gbl.Params.GetMethod = true; Gbl.Params.GetMethod = true;
Gbl.ContentReceivedByCGI = Act_CONT_NORM; Par_SetContentReceivedByCGI (Act_CONT_NORM);
/* Get content length */ /* Get content length */
Gbl.Params.ContentLength = strlen (getenv ("QUERY_STRING")); 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"))) if (!strncmp (ContentType,"multipart/form-data",strlen ("multipart/form-data")))
{ {
Gbl.ContentReceivedByCGI = Act_CONT_DATA; Par_SetContentReceivedByCGI (Act_CONT_DATA);
Par_GetBoundary (); Par_GetBoundary ();
return Fil_ReadStdinIntoTmpFile (); return Fil_ReadStdinIntoTmpFile ();
} }
@ -134,7 +160,7 @@ bool Par_GetQueryString (void)
} }
else else
{ {
Gbl.ContentReceivedByCGI = Act_CONT_NORM; Par_SetContentReceivedByCGI (Act_CONT_NORM);
/* Allocate memory for query string */ /* Allocate memory for query string */
if ((Gbl.Params.QueryString = malloc (Gbl.Params.ContentLength + 1)) == NULL) if ((Gbl.Params.QueryString = malloc (Gbl.Params.ContentLength + 1)) == NULL)
@ -225,7 +251,7 @@ void Par_CreateListOfParams (void)
/***** Get list *****/ /***** Get list *****/
if (Gbl.Params.ContentLength) 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 // The current element in the list has the length of the searched parameter
// Check if the name of the parameter is the same // Check if the name of the parameter is the same
switch (Gbl.ContentReceivedByCGI) switch (Par_GetContentReceivedByCGI ())
{ {
case Act_CONT_NORM: case Act_CONT_NORM:
ParamFound = !strncmp (ParamName,&Gbl.Params.QueryString[Param->Name.Start], ParamFound = !strncmp (ParamName,&Gbl.Params.QueryString[Param->Name.Start],
@ -580,7 +606,7 @@ unsigned Par_GetParameter (tParamType ParamType,const char *ParamName,
} }
/* Copy parameter value */ /* Copy parameter value */
switch (Gbl.ContentReceivedByCGI) switch (Par_GetContentReceivedByCGI ())
{ {
case Act_CONT_NORM: case Act_CONT_NORM:
if (PtrDst) if (PtrDst)

View File

@ -63,6 +63,8 @@ typedef enum
/***************************** Public prototypes *****************************/ /***************************** Public prototypes *****************************/
/*****************************************************************************/ /*****************************************************************************/
Act_Content_t Par_GetContentReceivedByCGI (void);
bool Par_GetQueryString (void); bool Par_GetQueryString (void);
void Par_CreateListOfParams (void); void Par_CreateListOfParams (void);
void Par_FreeParams (void); void Par_FreeParams (void);

View File

@ -753,88 +753,93 @@ void Str_ChangeFormat (Str_ChangeFrom_t ChangeFrom,Str_ChangeTo_t ChangeTo,
switch (ChangeFrom) switch (ChangeFrom)
{ {
case Str_FROM_FORM: case Str_FROM_FORM:
if (Gbl.ContentReceivedByCGI == Act_CONT_DATA) switch (Par_GetContentReceivedByCGI ())
// The form contained data and was sent with content type multipart/form-data {
switch (Ch) case Act_CONT_NORM:
{ // The form contained text and was sent with content type application/x-www-form-urlencoded
case 0x20: /* Space */ switch (Ch)
case 0x22: /* Change double comilla --> "&#34;" */ {
case 0x23: /* '#' */ case '+': /* Change every '+' to a space */
case 0x26: /* Change '&' --> "&#38;" */ IsSpecialChar = true;
case 0x27: /* Change single comilla --> "&#39;" to avoid SQL code injection */ LengthSpecStrSrc = 1;
case 0x2C: /* ',' */ SpecialChar = 0x20;
case 0x2F: /* '/' */ break;
case 0x3A: /* ':' */ case '%': /* Change "%XX" --> "&#decimal_number;" (from 0 to 255) */
case 0x3B: /* ';' */ /* Change "%uXXXX" --> "&#decimal number; (from 0 to 65535) */
case 0x3C: /* '<' --> "&#60;" */ IsSpecialChar = true;
case 0x3E: /* '>' --> "&#62;" */ if (*(PtrSrc + 1) == 'u')
case 0x3F: /* '?' */ {
case 0x40: /* '@' */ sscanf (PtrSrc + 2,"%4X",&SpecialChar);
case 0x5C: /* '\\' */ LengthSpecStrSrc = 6;
IsSpecialChar = true; }
LengthSpecStrSrc = 1; else
SpecialChar = (unsigned int) Ch; {
break; sscanf (PtrSrc + 1,"%2X",&SpecialChar);
default: LengthSpecStrSrc = 3;
if (Ch < 0x20 || Ch > 0x7F) }
{ /* 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 --> &#35753;
^ ^ ^
| | |
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: &#35753;
*/
break;
case 0x27: /* Change single comilla --> "&#39;" to avoid SQL code injection */
case 0x5C: /* '\\' */
IsSpecialChar = true; IsSpecialChar = true;
LengthSpecStrSrc = 1; LengthSpecStrSrc = 1;
SpecialChar = (unsigned int) Ch; SpecialChar = (unsigned int) Ch;
} break;
else default:
{
IsSpecialChar = false; IsSpecialChar = false;
NumPrintableCharsFromReturn++; NumPrintableCharsFromReturn++;
ThereIsSpaceChar = false; ThereIsSpaceChar = false;
} break;
break; }
} break;
else // Gbl.ContentReceivedByCGI == Act_CONTENT_NORM case Act_CONT_DATA:
// The form contained text and was sent with content type application/x-www-form-urlencoded // The form contained data and was sent with content type multipart/form-data
switch (Ch) switch (Ch)
{ {
case '+': /* Change every '+' to a space */ case 0x20: /* Space */
IsSpecialChar = true; case 0x22: /* Change double comilla --> "&#34;" */
LengthSpecStrSrc = 1; case 0x23: /* '#' */
SpecialChar = 0x20; case 0x26: /* Change '&' --> "&#38;" */
break; case 0x27: /* Change single comilla --> "&#39;" to avoid SQL code injection */
case '%': /* Change "%XX" --> "&#decimal_number;" (from 0 to 255) */ case 0x2C: /* ',' */
/* Change "%uXXXX" --> "&#decimal number; (from 0 to 65535) */ case 0x2F: /* '/' */
IsSpecialChar = true; case 0x3A: /* ':' */
if (*(PtrSrc + 1) == 'u') case 0x3B: /* ';' */
{ case 0x3C: /* '<' --> "&#60;" */
sscanf (PtrSrc + 2,"%4X",&SpecialChar); case 0x3E: /* '>' --> "&#62;" */
LengthSpecStrSrc = 6; case 0x3F: /* '?' */
} case 0x40: /* '@' */
else case 0x5C: /* '\\' */
{ IsSpecialChar = true;
sscanf (PtrSrc + 1,"%2X",&SpecialChar); LengthSpecStrSrc = 1;
LengthSpecStrSrc = 3; SpecialChar = (unsigned int) Ch;
} break;
/* Some special characters, like a chinese character, default:
can be received from a form in a format like this: if (Ch < 0x20 || Ch > 0x7F)
%26%2335753%3B --> %26 %23 3 5 7 5 3 %3B --> &#35753; {
^ ^ ^ IsSpecialChar = true;
| | | LengthSpecStrSrc = 1;
SpecialChar SpecialChar SpecialChar SpecialChar = (unsigned int) Ch;
Here one chinese character is converted }
to 2 special chars + 5 normal chars + 1 special char, else
and finally is stored as the following 8 bytes: &#35753; {
*/ IsSpecialChar = false;
break; NumPrintableCharsFromReturn++;
case 0x27: /* Change single comilla --> "&#39;" to avoid SQL code injection */ ThereIsSpaceChar = false;
case 0x5C: /* '\\' */ }
IsSpecialChar = true; break;
LengthSpecStrSrc = 1; }
SpecialChar = (unsigned int) Ch; break;
break; }
default:
IsSpecialChar = false;
NumPrintableCharsFromReturn++;
ThereIsSpaceChar = false;
break;
}
break; break;
case Str_FROM_HTML: case Str_FROM_HTML:
case Str_FROM_TEXT: case Str_FROM_TEXT: