From 76bbc30ed9232aff11003ffff60378370cc0eb2e Mon Sep 17 00:00:00 2001 From: Albert Gasset Date: Mon, 18 Mar 2019 14:29:23 +0100 Subject: [PATCH] MOBULE-2838 ws: convertValuesToString improvements - Skip null and undefined values. They were ignored when sent as POST parameters but are not accepted when sent as JSON. - Return null instead if some string become empty after stripping Unicode. Previously we were throwing an exception. - Convert boolean to "0" and "1". Previously we wre using "true" and "false", which are only accepted as POST parameters. --- src/classes/site.ts | 7 ++-- src/core/user/providers/user.ts | 4 +- src/providers/ws.ts | 68 ++++++++++++++++++++++----------- 3 files changed, 50 insertions(+), 29 deletions(-) diff --git a/src/classes/site.ts b/src/classes/site.ts index e103ab63a..a78ff9911 100644 --- a/src/classes/site.ts +++ b/src/classes/site.ts @@ -573,10 +573,9 @@ export class CoreSite { const originalData = data; - // Convert the values to string before starting the cache process. - try { - data = this.wsProvider.convertValuesToString(data, wsPreSets.cleanUnicode); - } catch (e) { + // Convert arguments to strings before starting the cache process. + data = this.wsProvider.convertValuesToString(data, wsPreSets.cleanUnicode); + if (data == null) { // Empty cleaned text found. return Promise.reject(this.utils.createFakeWSError('core.unicodenotsupportedcleanerror', true)); } diff --git a/src/core/user/providers/user.ts b/src/core/user/providers/user.ts index 928fb7bff..dd87758d8 100644 --- a/src/core/user/providers/user.ts +++ b/src/core/user/providers/user.ts @@ -250,8 +250,8 @@ export class CoreUserProvider { this.logger.debug(`Get user with ID '${userId}'`); wsName = 'core_user_get_users_by_field'; data = { - 'field': 'id', - 'values[0]': userId + field: 'id', + values: [userId] }; } diff --git a/src/providers/ws.ts b/src/providers/ws.ts index 7145ae55f..10eb3821e 100644 --- a/src/providers/ws.ts +++ b/src/providers/ws.ts @@ -284,32 +284,55 @@ export class CoreWSProvider { /** * Converts an objects values to strings where appropriate. - * Arrays (associative or otherwise) will be maintained. + * Arrays (associative or otherwise) will be maintained, null values will be removed. * * @param {object} data The data that needs all the non-object values set to strings. * @param {boolean} [stripUnicode] If Unicode long chars need to be stripped. - * @return {object} The cleaned object, with multilevel array and objects preserved. + * @return {object} The cleaned object or null if some strings becomes empty after stripping Unicode. */ - convertValuesToString(data: object, stripUnicode?: boolean): object { - let result; - if (!Array.isArray(data) && typeof data == 'object') { - result = {}; - } else { - result = []; - } + convertValuesToString(data: any, stripUnicode?: boolean): any { + const result: any = Array.isArray(data) ? [] : {}; - for (const el in data) { - if (typeof data[el] == 'object') { - result[el] = this.convertValuesToString(data[el], stripUnicode); - } else { - if (typeof data[el] == 'string') { - result[el] = stripUnicode ? this.textUtils.stripUnicode(data[el]) : data[el]; - if (stripUnicode && data[el] != result[el] && result[el].trim().length == 0) { - throw new Error(); - } - } else { - result[el] = data[el] + ''; + for (const key in data) { + let value = data[key]; + + if (value == null) { + // Skip null or undefined value. + continue; + } else if (typeof value == 'object') { + // Object or array. + value = this.convertValuesToString(value, stripUnicode); + if (value == null) { + return null; } + } else if (typeof value == 'string') { + if (stripUnicode) { + const stripped = this.textUtils.stripUnicode(value); + if (stripped != value && stripped.trim().length == 0) { + return null; + } + value = stripped; + } + } else if (typeof value == 'boolean') { + /* Moodle does not allow "true" or "false" in WS parameters, only in POST parameters. + We've been using "true" and "false" for WS settings "filter" and "fileurl", + we keep it this way to avoid changing cache keys. */ + if (key == 'moodlewssettingfilter' || key == 'moodlewssettingfileurl') { + value = value ? 'true' : 'false'; + } else { + value = value ? '1' : '0'; + } + } else if (typeof value == 'number') { + value = String(value); + } else { + // Unknown type. + continue; + } + + if (Array.isArray(result)) { + result.push(value); + } else { + result[key] = value; } } @@ -688,9 +711,8 @@ export class CoreWSProvider { preSets.responseExpected = true; } - try { - data = this.convertValuesToString(data, preSets.cleanUnicode); - } catch (e) { + data = this.convertValuesToString(data || {}, preSets.cleanUnicode); + if (data == null) { // Empty cleaned text found. errorResponse.message = this.translate.instant('core.unicodenotsupportedcleanerror');