diff --git a/js/swad19.239.js b/js/swad19.239.5.js similarity index 97% rename from js/swad19.239.js rename to js/swad19.239.5.js index ec87ec68..747e0083 100644 --- a/js/swad19.239.js +++ b/js/swad19.239.5.js @@ -562,7 +562,7 @@ function updateExamPrint (idDiv,idInput,nameInput,Params,timeoutMsg) { clearTimeout (xmlHttpTimeout); // Response received ==> clear timeout if (idDiv) { var div = document.getElementById(idDiv); // Access to DIV - if (div) { + if (div) { div.innerHTML = objXMLHttp.responseText; // Update DIV content // Scripts in div got via AJAX are not executed ==> execute them @@ -602,8 +602,14 @@ function updateExamPrint (idDiv,idInput,nameInput,Params,timeoutMsg) { if (inputElems[i].checked) Params += ',' + inputElems[i].value; } - else - Params += '&' + nameInput + '=' + inputElem.value; + else { + // form value is always UTF-8 codified, even if other coding is specified in form + var val = inputElem.value; + + // Params += '&' + nameInput + '=' + encodeURIComponent(val); // UTF-8 escaped + // Params += '&' + nameInput + '=' + escape(val); // ISO-8859-1 escaped (deprecated) + Params += '&' + nameInput + '=' + getEscapedString(val); // ISO-8859-1 escaped, replacement for deprecated escape() + } } objXMLHttp.open('POST',ActionAJAX,true); @@ -622,6 +628,60 @@ function updateExamPrint (idDiv,idInput,nameInput,Params,timeoutMsg) { } } +// Escape except - _ . ! ~ * ' ( ) +// Escape the same chars as encodeURIComponent(), but in ISO-8859-1 +function getEscapedString (str) { + var escaped = ''; + + for (var i = 0; i < str.length; i++) { + const code = str.charCodeAt(i); + var esc; + + switch (true) { + case (code < 16): + esc = '%0' + code.toString(16).toUpperCase(); // %0X + break; + case (code >= 16 && code <= 32): + case (code >= 34 && code <= 38): + case (code == 43): // '+' + case (code == 44): // ',' + case (code == 47): // '/' + case (code >= 58 && code <= 64): + case (code >= 91 && code <= 94): + case (code == 96): // '`' + case (code >= 123 && code <= 125): + case (code >= 127 && code <= 255): + esc = '%' + code.toString(16).toUpperCase(); // %XX + break; + case (code >= 256): + esc = '%26%23' + code.toString(10) + '%3B'; // &#code; instead of %uXXXX + break; + default: + esc = str.charAt(i); + break; + } + escaped += esc; + } + + return escaped; +} + +/* +// To generate a table with the codification generated by escape() +// Copy the following code in https://playcode.io/ +//----------------------------------------------------------------------------- +var arr = []; +for(var i=0;i<256;i++) { + var char=String.fromCharCode(i); + arr.push({ + character:char, + encodeURIComponent:encodeURIComponent(char), + escape:escape(char) + }); +} +console.table(arr); +//----------------------------------------------------------------------------- +*/ /*****************************************************************************/ /********** Automatic refresh of current match question using AJAX ***********/ /*****************************************************************************/ diff --git a/swad_changelog.h b/swad_changelog.h index ecf078d7..863dea10 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -557,10 +557,11 @@ enscript -2 --landscape --color --file-align=2 --highlight --line-numbers -o - * En OpenSWAD: ps2pdf source.ps destination.pdf */ -#define Log_PLATFORM_VERSION "SWAD 19.239.4 (2020-05-20)" +#define Log_PLATFORM_VERSION "SWAD 19.239.5 (2020-05-21)" #define CSS_FILE "swad19.238.2.css" -#define JS_FILE "swad19.239.js" +#define JS_FILE "swad19.239.5.js" /* + Version 19.239.5: May 21, 2020 Fixed bug in charset in answer forms in exam prints. (301405 lines) Version 19.239.4: May 20, 2020 Fixed bug listing user's exam prints. (301332 lines) Version 19.239.3: May 20, 2020 Fixed bugs removing exam prints in a course. Don't remove user's production in a course when removing the user individually. (301316 lines) @@ -1081,7 +1082,7 @@ ALTER TABLE tst_exams CHANGE COLUMN EndTime EndTime DATETIME NOT NULL; Version 19.155.6: Mar 26, 2020 Code refactoring in matches. (284479 lines) Version 19.155.5: Mar 26, 2020 Code refactoring in tests. (284480 lines) Version 19.155.4: Mar 26, 2020 Code refactoring in tests. (284476 lines) - Version 19.155.3: Mar 27, 2020 Code refactoring in pass to parameters of functions. (284476 lines) + Version 19.155.3: Mar 26, 2020 Code refactoring in pass to parameters of functions. (284476 lines) Version 19.155.2: Mar 26, 2020 Code refactoring in tests. (284414 lines) Version 19.155.1: Mar 26, 2020 Code refactoring in tests. (284430 lines) Version 19.155: Mar 25, 2020 Big code refactoring in pass to parameters of functions. (284446 lines) diff --git a/swad_exam_session.c b/swad_exam_session.c index 4300e5c1..ce1fc7cd 100644 --- a/swad_exam_session.c +++ b/swad_exam_session.c @@ -151,30 +151,30 @@ void ExaSes_ListSessions (struct Exa_Exams *Exams, { extern const char *Hlp_ASSESSMENT_Exams_sessions; extern const char *Txt_Sessions; - char *SubQuery; + char *GroupsSubQuery; MYSQL_RES *mysql_res; unsigned NumSessions; long SesCodToBeEdited; bool PutFormNewSession; /***** Get data of sessions from database *****/ - /* Fill subquery for exam */ + /* Fill groups subquery for exam */ if (Gbl.Crs.Grps.WhichGrps == Grp_MY_GROUPS) { - if (asprintf (&SubQuery," AND" - "(SesCod NOT IN" - " (SELECT SesCod FROM exa_groups)" - " OR" - " SesCod IN" - " (SELECT exa_groups.SesCod" - " FROM exa_groups,crs_grp_usr" - " WHERE crs_grp_usr.UsrCod=%ld" - " AND exa_groups.GrpCod=crs_grp_usr.GrpCod))", + if (asprintf (&GroupsSubQuery," AND" + "(SesCod NOT IN" + " (SELECT SesCod FROM exa_groups)" + " OR" + " SesCod IN" + " (SELECT exa_groups.SesCod" + " FROM exa_groups,crs_grp_usr" + " WHERE crs_grp_usr.UsrCod=%ld" + " AND exa_groups.GrpCod=crs_grp_usr.GrpCod))", Gbl.Usrs.Me.UsrDat.UsrCod) < 0) Lay_NotEnoughMemoryExit (); } else // Gbl.Crs.Grps.WhichGrps == Grp_ALL_GROUPS - if (asprintf (&SubQuery,"%s","") < 0) + if (asprintf (&GroupsSubQuery,"%s","") < 0) Lay_NotEnoughMemoryExit (); /* Make query */ @@ -193,10 +193,10 @@ void ExaSes_ListSessions (struct Exa_Exams *Exams, " WHERE ExaCod=%ld%s" " ORDER BY SesCod", Exam->ExaCod, - SubQuery); + GroupsSubQuery); /* Free allocated memory for subquery */ - free (SubQuery); + free (GroupsSubQuery); /***** Begin box *****/ Exams->ExaCod = Exam->ExaCod; diff --git a/swad_form.c b/swad_form.c index 63677a07..90033755 100644 --- a/swad_form.c +++ b/swad_form.c @@ -157,12 +157,19 @@ static void Frm_StartFormInternal (Act_Action_t NextAction,bool PutParameterLoca } } +/* + Form without action are used in exams. + The accept-charset attribute specifies the character encodings that are to be used for the form submission + But this type of form is sent via AJAX ==> + ==> we use the value property of input fields to build the parameters sent using XMLHttp.send ==> + ==> the value property is always codified in UTF-8 ==> accept-charset is irrelevant +*/ void Frm_StartFormNoAction (void) { if (!Gbl.Form.Inside) { /* Begin form */ - HTM_Txt ("
"); // Form that can not be submitted, to avoid enter key to send it Gbl.Form.Inside = true; diff --git a/swad_string.c b/swad_string.c index aa647b03..a798e410 100644 --- a/swad_string.c +++ b/swad_string.c @@ -1111,9 +1111,20 @@ void Str_ChangeFormat (Str_ChangeFrom_t ChangeFrom,Str_ChangeTo_t ChangeTo, 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, - are received from a form in a format like this: + can be received from a form in a format like this: %26%2335753%3B --> %26 %23 3 5 7 5 3 %3B --> 让 ^ ^ ^ | | | @@ -1122,8 +1133,6 @@ void Str_ChangeFormat (Str_ChangeFrom_t ChangeFrom,Str_ChangeTo_t ChangeTo, to 2 special chars + 5 normal chars + 1 special char, and finally is stored as the following 8 bytes: 让 */ - sscanf (PtrSrc + 1,"%2X",&SpecialChar); - LengthSpecStrSrc = 3; break; case 0x27: /* Change single comilla --> "'" to avoid SQL code injection */ case 0x5C: /* '\\' */ @@ -1430,9 +1439,10 @@ void Str_ChangeFormat (Str_ChangeFrom_t ChangeFrom,Str_ChangeTo_t ChangeTo, break; default: /* The rest of special chars are stored as special code */ snprintf (StrSpecialChar,sizeof (StrSpecialChar), - (ChangeTo == Str_TO_TEXT || - ChangeTo == Str_TO_MARKDOWN) ? "%c" : - "&#%u;", + (SpecialChar < 256 && + (ChangeTo == Str_TO_TEXT || + ChangeTo == Str_TO_MARKDOWN)) ? "%c" : + "&#%u;", SpecialChar); NumPrintableCharsFromReturn++; ThereIsSpaceChar = false;