mirror of https://github.com/acanas/swad-core.git
Version 15.168
This commit is contained in:
parent
e95a3e2e52
commit
a0617c1edb
|
@ -138,13 +138,14 @@
|
|||
/****************************** Public constants *****************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
#define Log_PLATFORM_VERSION "SWAD 15.167 (2016-03-29)"
|
||||
#define Log_PLATFORM_VERSION "SWAD 15.168 (2016-03-29)"
|
||||
#define CSS_FILE "swad15.165.5.css"
|
||||
#define JS_FILE "swad15.131.3.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 15.168: Mar 30, 2016 When content is normal, all parameters are retrieved in a list. (197085 lines)
|
||||
Version 15.167: Mar 30, 2016 Query string is allocated to the exact needed size to optimize memory. (196998 lines)
|
||||
Version 15.166.1: Mar 30, 2016 Fixed bug while reading a parameter. (196959 lines)
|
||||
Version 15.166: Mar 30, 2016 Changes in form to edit a test question.
|
||||
|
|
|
@ -105,8 +105,10 @@ void Gbl_InitializeGlobals (void)
|
|||
|
||||
Gbl.WebService.IsWebService = false;
|
||||
|
||||
Gbl.ContentLength = 0;
|
||||
Gbl.QueryString = NULL;
|
||||
Gbl.Params.ContentLength = 0;
|
||||
Gbl.Params.QueryString = NULL;
|
||||
Gbl.Params.List = NULL;
|
||||
Gbl.Params.GetMethod = false;
|
||||
|
||||
Gbl.F.Out = stdout;
|
||||
Gbl.F.Tmp = NULL;
|
||||
|
@ -117,7 +119,6 @@ void Gbl_InitializeGlobals (void)
|
|||
|
||||
Gbl.Error = false;
|
||||
|
||||
Gbl.GetMethod = false;
|
||||
|
||||
Gbl.Layout.WritingHTMLStart =
|
||||
Gbl.Layout.HTMLStartWritten =
|
||||
|
|
|
@ -95,13 +95,23 @@ struct Globals
|
|||
bool Inside; // Set to true inside a form to avoid nested forms
|
||||
} Form;
|
||||
bool Error;
|
||||
bool GetMethod; // Am I accessed using GET method?
|
||||
struct soap *soap; // gSOAP runtime environment
|
||||
|
||||
struct
|
||||
{
|
||||
size_t ContentLength;
|
||||
char *QueryString; // String allocated dynamically with the arguments sent to the CGI
|
||||
struct Param *List; // Linked list of parameters
|
||||
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_CONTENT_DATA (if CONTENT_TYPE==multipart/form-data) */
|
||||
Act_CONTENT_NORM (if CONTENT_TYPE==text/plain) or
|
||||
Act_CONTENT_DATA (if CONTENT_TYPE==multipart/form-data) */
|
||||
char DelimiterString[1000];
|
||||
char DelimiterStringIncludingInitialRet[2+1000];
|
||||
|
||||
struct soap *soap; // gSOAP runtime environment
|
||||
|
||||
struct
|
||||
{
|
||||
bool WritingHTMLStart; // Used to avoid writing the HTML head when aborting program on error
|
||||
|
@ -115,7 +125,7 @@ struct Globals
|
|||
bool LockedTables;
|
||||
} DB;
|
||||
|
||||
bool HiddenParamsInsertedIntoDB; // Indica si se ha insertado algún parameter in the database in esta ejecución
|
||||
bool HiddenParamsInsertedIntoDB; // If parameters are inserted in the database in this execution
|
||||
|
||||
/* To compute execution time of the program */
|
||||
struct timeval tvStart,tvPageCreated,tvPageSent;
|
||||
|
@ -702,8 +712,6 @@ struct Globals
|
|||
float MaxPercent;
|
||||
} DegPhotos;
|
||||
} Stat;
|
||||
size_t ContentLength;
|
||||
char *QueryString; // String allocated dynamically with the arguments sent to the CGI
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
@ -369,7 +369,7 @@ static void Lay_WritePageTitle (void)
|
|||
|
||||
fprintf (Gbl.F.Out,"<title>");
|
||||
|
||||
if (Gbl.GetMethod && Gbl.CurrentDeg.Deg.DegCod > 0)
|
||||
if (Gbl.Params.GetMethod && Gbl.CurrentDeg.Deg.DegCod > 0)
|
||||
{
|
||||
fprintf (Gbl.F.Out,"%s > %s",
|
||||
Cfg_PLATFORM_SHORT_NAME,
|
||||
|
|
173
swad_parameter.c
173
swad_parameter.c
|
@ -59,6 +59,8 @@ extern struct Globals Gbl;
|
|||
/***************************** Private prototypes ****************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
static void Par_GetParameters (void);
|
||||
|
||||
static void Par_ShowErrorReadingParam (const char *ParamName,const char *ExpectedChar,int Ch);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -76,18 +78,18 @@ bool Par_GetQueryString (void)
|
|||
if (!strcmp (Method,"GET"))
|
||||
{
|
||||
/***** GET method *****/
|
||||
Gbl.GetMethod = true;
|
||||
Gbl.Params.GetMethod = true;
|
||||
Gbl.ContentReceivedByCGI = Act_CONTENT_NORM;
|
||||
|
||||
/* Get content length */
|
||||
Gbl.ContentLength = strlen (getenv ("QUERY_STRING"));
|
||||
Gbl.Params.ContentLength = strlen (getenv ("QUERY_STRING"));
|
||||
|
||||
/* Allocate memory for query string */
|
||||
if ((Gbl.QueryString = (char *) malloc (Gbl.ContentLength + 1)) == NULL)
|
||||
if ((Gbl.Params.QueryString = (char *) malloc (Gbl.Params.ContentLength + 1)) == NULL)
|
||||
return false;
|
||||
|
||||
/* Copy query string from environment variable */
|
||||
strcpy (Gbl.QueryString,getenv ("QUERY_STRING"));
|
||||
strcpy (Gbl.Params.QueryString,getenv ("QUERY_STRING"));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -96,7 +98,7 @@ bool Par_GetQueryString (void)
|
|||
if (getenv ("CONTENT_LENGTH"))
|
||||
{
|
||||
strcpy (UnsignedLongStr,getenv ("CONTENT_LENGTH"));
|
||||
if (sscanf (UnsignedLongStr,"%lu",&Gbl.ContentLength) != 1)
|
||||
if (sscanf (UnsignedLongStr,"%lu",&Gbl.Params.ContentLength) != 1)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
|
@ -132,18 +134,22 @@ bool Par_GetQueryString (void)
|
|||
Gbl.ContentReceivedByCGI = Act_CONTENT_NORM;
|
||||
|
||||
/* Allocate memory for query string */
|
||||
if ((Gbl.QueryString = (char *) malloc (Gbl.ContentLength + 1)) == NULL)
|
||||
if ((Gbl.Params.QueryString = (char *) malloc (Gbl.Params.ContentLength + 1)) == NULL)
|
||||
return false;
|
||||
|
||||
/* Copy query string from stdin */
|
||||
if (fread ((void *) Gbl.QueryString,sizeof (char),Gbl.ContentLength,stdin) != Gbl.ContentLength)
|
||||
if (fread ((void *) Gbl.Params.QueryString,sizeof (char),Gbl.Params.ContentLength,stdin) != Gbl.Params.ContentLength)
|
||||
{
|
||||
Gbl.QueryString[0] = '\0';
|
||||
Gbl.Params.QueryString[0] = '\0';
|
||||
return false;
|
||||
}
|
||||
Gbl.QueryString[Gbl.ContentLength] = '\0';
|
||||
Gbl.Params.QueryString[Gbl.Params.ContentLength] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
if (Gbl.ContentReceivedByCGI == Act_CONTENT_NORM)
|
||||
Par_GetParameters ();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -153,8 +159,8 @@ bool Par_GetQueryString (void)
|
|||
|
||||
void Par_FreeQueryString (void)
|
||||
{
|
||||
if (Gbl.QueryString)
|
||||
free ((void *) Gbl.QueryString);
|
||||
if (Gbl.Params.QueryString)
|
||||
free ((void *) Gbl.Params.QueryString);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -447,6 +453,95 @@ unsigned Par_GetParAndChangeFormat (const char *ParamName,char *ParamValue,size_
|
|||
return NumTimes;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/************************* Get the value of a parameter **********************/
|
||||
/*****************************************************************************/
|
||||
// Return the number of parameters found
|
||||
|
||||
#define Par_LENGTH_OF_STR_BEFORE_PARAM 38 // Length of "CONTENT-DISPOSITION: FORM-DATA; NAME=\""
|
||||
#define Par_MAX_BYTES_STR_AUX 1024
|
||||
|
||||
static void Par_GetParameters (void)
|
||||
{
|
||||
unsigned long i;
|
||||
struct Param *Param;
|
||||
struct Param *NewParam;
|
||||
|
||||
switch (Gbl.ContentReceivedByCGI)
|
||||
{
|
||||
case Act_CONTENT_NORM:
|
||||
if (Gbl.Params.QueryString == NULL)
|
||||
{
|
||||
Gbl.Params.List = NULL;
|
||||
return;
|
||||
}
|
||||
if (!Gbl.Params.QueryString[0])
|
||||
{
|
||||
Gbl.Params.List = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0;
|
||||
i < Gbl.Params.ContentLength;
|
||||
)
|
||||
{
|
||||
/* Allocate space for parameter */
|
||||
if ((NewParam = (struct Param *) malloc (sizeof (struct Param))) == NULL)
|
||||
Lay_ShowErrorAndExit ("Error allocating memory for parameter");
|
||||
|
||||
/* Point last element in list to this */
|
||||
if (i == 0)
|
||||
Gbl.Params.List = NewParam;
|
||||
else
|
||||
Param->Next = NewParam;
|
||||
|
||||
/* Point current element to the new just created */
|
||||
Param = NewParam;
|
||||
Param->Next = NULL;
|
||||
|
||||
/* Get parameter name */
|
||||
Param->Name.Start = i;
|
||||
Param->Name.Length = strcspn (&Gbl.Params.QueryString[i],"=");
|
||||
|
||||
/* Get parameter value */
|
||||
i += Param->Name.Length;
|
||||
if (i < Gbl.Params.ContentLength)
|
||||
{
|
||||
if (Gbl.Params.QueryString[i] == '=')
|
||||
{
|
||||
i++; // Skip '='
|
||||
Param->Value.Start = i;
|
||||
if (i < Gbl.Params.ContentLength)
|
||||
{
|
||||
Param->Value.Length = strcspn (&Gbl.Params.QueryString[i],"&");
|
||||
i += Param->Value.Length;
|
||||
if (i < Gbl.Params.ContentLength)
|
||||
if (Gbl.Params.QueryString[i] == '&')
|
||||
i++; // Skip '&'
|
||||
}
|
||||
else
|
||||
Param->Value.Length = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Param->Value.Start = i;
|
||||
Param->Value.Length = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Param->Value.Start = i;
|
||||
Param->Value.Length = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Act_CONTENT_DATA:
|
||||
// TODO: Implement
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/************************* Get the value of a parameter **********************/
|
||||
/*****************************************************************************/
|
||||
|
@ -463,9 +558,9 @@ unsigned Par_GetParameter (tParamType ParamType,const char *ParamName,
|
|||
size_t BytesAlreadyCopied = 0;
|
||||
int Ch;
|
||||
unsigned i;
|
||||
char *PtrSrc;
|
||||
struct Param *Param;
|
||||
char *PtrDst;
|
||||
char *PtrStartOfParam;
|
||||
const char *PtrSrc = NULL;
|
||||
int Result;
|
||||
unsigned NumTimes = 0;
|
||||
bool ParamFound = false;
|
||||
|
@ -479,7 +574,7 @@ unsigned Par_GetParameter (tParamType ParamType,const char *ParamName,
|
|||
switch (Gbl.ContentReceivedByCGI)
|
||||
{
|
||||
case Act_CONTENT_NORM:
|
||||
if (Gbl.GetMethod) // Only some selected parameters can be passed by GET method
|
||||
if (Gbl.Params.GetMethod) // Only some selected parameters can be passed by GET method
|
||||
{
|
||||
if (strcmp (ParamName,"cty") && // To enter directly to a country
|
||||
strcmp (ParamName,"ins") && // To enter directly to an institution
|
||||
|
@ -493,38 +588,28 @@ unsigned Par_GetParameter (tParamType ParamType,const char *ParamName,
|
|||
strcmp (ParamName,"key")) // To verify an email address
|
||||
return 0; // Return no-parameters-found when method is GET and parameter name is not one of these
|
||||
}
|
||||
PtrSrc = Gbl.QueryString;
|
||||
|
||||
PtrDst = ParamValue;
|
||||
Param = Gbl.Params.List;
|
||||
for (NumTimes = 0;
|
||||
NumTimes < 1 || ParamType == Par_PARAM_MULTIPLE;
|
||||
NumTimes++)
|
||||
{
|
||||
ParamFound = false;
|
||||
do
|
||||
{
|
||||
/* If method is GET ==> do case insensitive comparison */
|
||||
PtrStartOfParam = strstr (PtrSrc,ParamName);
|
||||
if (PtrStartOfParam)
|
||||
{
|
||||
// String ParamName found inside Gbl.QueryString
|
||||
if (*(PtrStartOfParam + ParamNameLength) == '=')
|
||||
for (ParamFound = false;
|
||||
Param != NULL && !ParamFound;
|
||||
Param = Param->Next)
|
||||
if (ParamNameLength == Param->Name.Length)
|
||||
if (!strncmp (ParamName,&Gbl.Params.QueryString[Param->Name.Start],
|
||||
Param->Name.Length))
|
||||
{
|
||||
// Just after the name of the parameter, must be found a '=' symbol
|
||||
if (PtrStartOfParam == Gbl.QueryString) // The parameter is just at start
|
||||
ParamFound = true;
|
||||
else if (*(PtrStartOfParam - 1) == '&') // The parameter is not at start, but just after an "&" separator
|
||||
ParamFound = true;
|
||||
else // String has been found at the end of another parameter
|
||||
PtrSrc = PtrStartOfParam + ParamNameLength;
|
||||
ParamFound = true;
|
||||
if ((BytesToCopy = Param->Value.Length))
|
||||
PtrSrc = &Gbl.Params.QueryString[Param->Value.Start];
|
||||
}
|
||||
else // String has been found, but it is not a parameter
|
||||
PtrSrc = PtrStartOfParam + ParamNameLength;
|
||||
}
|
||||
}
|
||||
while (PtrStartOfParam != NULL && !ParamFound);
|
||||
if (!ParamFound) // Not found ==> PtrStartOfParam == NULL
|
||||
|
||||
if (!ParamFound)
|
||||
break;
|
||||
PtrSrc = PtrStartOfParam + ParamNameLength + 1; // Add 1 due to the '=' symbol
|
||||
|
||||
if (NumTimes)
|
||||
{
|
||||
if (BytesAlreadyCopied + 1 > MaxBytes)
|
||||
|
@ -537,7 +622,7 @@ unsigned Par_GetParameter (tParamType ParamType,const char *ParamName,
|
|||
*PtrDst++ = Par_SEPARATOR_PARAM_MULTIPLE; // Separator in the destination string
|
||||
BytesAlreadyCopied++;
|
||||
}
|
||||
BytesToCopy = strcspn (PtrSrc,"&"); // The & charecter is the separator of two parameters
|
||||
|
||||
if (BytesAlreadyCopied + BytesToCopy > MaxBytes)
|
||||
{
|
||||
sprintf (Gbl.Message,"Parameter <strong>%s</strong> too large,"
|
||||
|
@ -545,10 +630,12 @@ unsigned Par_GetParameter (tParamType ParamType,const char *ParamName,
|
|||
ParamName,(unsigned long) MaxBytes);
|
||||
Lay_ShowErrorAndExit (Gbl.Message);
|
||||
}
|
||||
strncpy (PtrDst,PtrSrc,BytesToCopy);
|
||||
BytesAlreadyCopied += BytesToCopy;
|
||||
PtrDst += BytesToCopy;
|
||||
PtrSrc += BytesToCopy;
|
||||
if (BytesToCopy)
|
||||
{
|
||||
strncpy (PtrDst,PtrSrc,BytesToCopy);
|
||||
BytesAlreadyCopied += BytesToCopy;
|
||||
PtrDst += BytesToCopy;
|
||||
}
|
||||
}
|
||||
*PtrDst = '\0'; // strncpy() does not add the final NULL
|
||||
break;
|
||||
|
|
|
@ -34,6 +34,18 @@
|
|||
/************************** Public types and constants ***********************/
|
||||
/*****************************************************************************/
|
||||
|
||||
struct StartLength
|
||||
{
|
||||
unsigned long Start;
|
||||
size_t Length;
|
||||
};
|
||||
struct Param
|
||||
{
|
||||
struct StartLength Name;
|
||||
struct StartLength Value;
|
||||
struct Param *Next;
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
Par_PARAM_SINGLE,
|
||||
|
|
Loading…
Reference in New Issue