From 3c49e9e153014d5a7b11821f52f2894c943d285b Mon Sep 17 00:00:00 2001 From: wellwelwel <46850407+wellwelwel@users.noreply.github.com> Date: Fri, 12 Apr 2024 15:30:34 -0300 Subject: [PATCH 1/7] fix: revert breaking change in results creation --- lib/helpers.js | 40 +++++++++++++++++-- lib/parsers/binary_parser.js | 15 +++---- lib/parsers/text_parser.js | 17 ++++---- .../unit/helpers/create-safe-object.test.mjs | 20 ++++++++++ .../parsers/prototype-binary-results.test.mjs | 27 +++++-------- .../parsers/prototype-text-results.test.mjs | 29 +++++--------- 6 files changed, 89 insertions(+), 59 deletions(-) create mode 100644 test/esm/unit/helpers/create-safe-object.test.mjs diff --git a/lib/helpers.js b/lib/helpers.js index 2a8f80367f..27b87121d7 100644 --- a/lib/helpers.js +++ b/lib/helpers.js @@ -16,7 +16,7 @@ */ function srcEscape(str) { return JSON.stringify({ - [str]: 1 + [str]: 1, }).slice(1, -3); } @@ -29,7 +29,7 @@ try { const REQUIRE_TERMINATOR = ''; highlightFn = require(`cardinal${REQUIRE_TERMINATOR}`).highlight; } catch (err) { - highlightFn = text => { + highlightFn = (text) => { if (!cardinalRecommended) { // eslint-disable-next-line no-console console.log('For nicer debug output consider install cardinal@^2.0.0'); @@ -56,10 +56,44 @@ exports.printDebugWithCode = printDebugWithCode; */ function typeMatch(type, list, Types) { if (Array.isArray(list)) { - return list.some(t => type === Types[t]); + return list.some((t) => type === Types[t]); } return !!list; } exports.typeMatch = typeMatch; + +function createSafeObject() { + const nativeProps = ['hasOwnProperty', 'toString', 'valueOf']; + + const handler = { + get(_, prop, receiver) { + const isNativeProp = nativeProps.includes(prop); + + if (isNativeProp) { + return (...args) => Object.prototype[prop].apply(receiver, args); + } + + if (prop === '__proto__') { + return Object.prototype; + } + + return Reflect.get(...arguments); + }, + set(_, prop) { + const isNativeProp = nativeProps.includes(prop); + + if (isNativeProp || prop === '__proto__') { + return false; + } + + return Reflect.set(...arguments); + }, + }; + + const safePrototype = Object.create(Object.prototype); + return new Proxy(safePrototype, handler); +} + +exports.createSafeObject = createSafeObject; diff --git a/lib/parsers/binary_parser.js b/lib/parsers/binary_parser.js index 26ac7893e8..2c4debc500 100644 --- a/lib/parsers/binary_parser.js +++ b/lib/parsers/binary_parser.js @@ -122,13 +122,7 @@ function compile(fields, options, config) { if (options.rowsAsArray) { parserFn(`const result = new Array(${fields.length});`); } else { - parserFn('const result = Object.create(null);'); - parserFn(`Object.defineProperty(result, "constructor", { - value: Object.create(null), - writable: false, - configurable: false, - enumerable: false - });`); + parserFn('const result = createSafeObject();'); } // Global typeCast @@ -161,7 +155,7 @@ function compile(fields, options, config) { } else if (options.nestTables === true) { tableName = helpers.srcEscape(fields[i].table); parserFn( - `if (!result[${tableName}]) result[${tableName}] = Object.create(null);`, + `if (!result[${tableName}]) result[${tableName}] = createSafeObject();`, ); lvalue = `result[${tableName}][${fieldName}]`; } else if (options.rowsAsArray) { @@ -207,7 +201,10 @@ function compile(fields, options, config) { parserFn.toString(), ); } - return parserFn.toFunction({ wrap }); + return parserFn.toFunction({ + wrap, + createSafeObject: helpers.createSafeObject, + }); } function getBinaryParser(fields, options, config) { diff --git a/lib/parsers/text_parser.js b/lib/parsers/text_parser.js index e757b45623..28d9132f8f 100644 --- a/lib/parsers/text_parser.js +++ b/lib/parsers/text_parser.js @@ -131,13 +131,7 @@ function compile(fields, options, config) { if (options.rowsAsArray) { parserFn(`const result = new Array(${fields.length});`); } else { - parserFn('const result = Object.create(null);'); - parserFn(`Object.defineProperty(result, "constructor", { - value: Object.create(null), - writable: false, - configurable: false, - enumerable: false - });`); + parserFn('const result = createSafeObject();'); } const resultTables = {}; @@ -150,7 +144,7 @@ function compile(fields, options, config) { resultTablesArray = Object.keys(resultTables); for (let i = 0; i < resultTablesArray.length; i++) { parserFn( - `result[${helpers.srcEscape(resultTablesArray[i])}] = Object.create(null);`, + `result[${helpers.srcEscape(resultTablesArray[i])}] = createSafeObject();`, ); } } @@ -203,9 +197,12 @@ function compile(fields, options, config) { ); } if (typeof options.typeCast === 'function') { - return parserFn.toFunction({ wrap }); + return parserFn.toFunction({ + wrap, + createSafeObject: helpers.createSafeObject, + }); } - return parserFn.toFunction(); + return parserFn.toFunction({ createSafeObject: helpers.createSafeObject }); } function getTextParser(fields, options, config) { diff --git a/test/esm/unit/helpers/create-safe-object.test.mjs b/test/esm/unit/helpers/create-safe-object.test.mjs new file mode 100644 index 0000000000..8a067617ee --- /dev/null +++ b/test/esm/unit/helpers/create-safe-object.test.mjs @@ -0,0 +1,20 @@ +import { describe, assert } from 'poku'; +import { describeOptions } from '../../../common.test.cjs'; +import { createSafeObject } from '../../../../lib/helpers.js'; + +describe('Creating a safe object', describeOptions); + +const stdObj = {}; +const safeObj = createSafeObject(); + +assert.deepStrictEqual(stdObj, safeObj, 'Ensure __proto__ is immutable'); +assert.throws(() => { + safeObj.__proto__ = { toString: () => true }; +}, 'Ensure safeObject is valid'); + +stdObj.__proto__ = { toString: () => true }; +assert.notDeepStrictEqual( + stdObj, + safeObj, + 'Ensure that the object is not the same as the poisoned __proto__', +); diff --git a/test/esm/unit/parsers/prototype-binary-results.test.mjs b/test/esm/unit/parsers/prototype-binary-results.test.mjs index a33eec077b..21268822e7 100644 --- a/test/esm/unit/parsers/prototype-binary-results.test.mjs +++ b/test/esm/unit/parsers/prototype-binary-results.test.mjs @@ -7,32 +7,23 @@ describe('Binary Parser: Prototype Sanitization', describeOptions); Promise.all([ test(async () => { - const expected = [{}]; - expected[0].test = 2; - - const [results] = await connection.query('SELECT 1+1 AS `test`'); - - assert.notDeepStrictEqual( - results, - expected, - `Ensure "results" doesn't contain a standard object ({})`, - ); - }), - test(async () => { - const expected = [Object.create(null)]; - expected[0].test = 2; + const expected = [ + { + test: 2, + }, + ]; const [results] = await connection.execute('SELECT 1+1 AS `test`'); assert.deepStrictEqual(results, expected, 'Ensure clean object "results"'); - assert.strictEqual( - Object.getPrototypeOf(results[0]), - null, + assert.deepStrictEqual( + JSON.stringify(Object.getPrototypeOf(results[0])), + JSON.stringify({}), 'Ensure clean properties in results items', ); assert.strictEqual( typeof results[0].toString, - 'undefined', + 'function', 'Re-check prototypes (manually) in results columns', ); assert.strictEqual( diff --git a/test/esm/unit/parsers/prototype-text-results.test.mjs b/test/esm/unit/parsers/prototype-text-results.test.mjs index 99a6a69312..ee25574c30 100644 --- a/test/esm/unit/parsers/prototype-text-results.test.mjs +++ b/test/esm/unit/parsers/prototype-text-results.test.mjs @@ -3,36 +3,27 @@ import { createConnection, describeOptions } from '../../../common.test.cjs'; const connection = createConnection().promise(); -describe('Text Parser: Prototype Sanitization', describeOptions); +describe('Binary Parser: Prototype Sanitization', describeOptions); Promise.all([ test(async () => { - const expected = [{}]; - expected[0].test = 2; - - const [results] = await connection.query('SELECT 1+1 AS `test`'); - - assert.notDeepStrictEqual( - results, - expected, - `Ensure "results" doesn't contain a standard object ({})`, - ); - }), - test(async () => { - const expected = [Object.create(null)]; - expected[0].test = 2; + const expected = [ + { + test: 2, + }, + ]; const [results] = await connection.query('SELECT 1+1 AS `test`'); assert.deepStrictEqual(results, expected, 'Ensure clean object "results"'); - assert.strictEqual( - Object.getPrototypeOf(results[0]), - null, + assert.deepStrictEqual( + JSON.stringify(Object.getPrototypeOf(results[0])), + JSON.stringify({}), 'Ensure clean properties in results items', ); assert.strictEqual( typeof results[0].toString, - 'undefined', + 'function', 'Re-check prototypes (manually) in results columns', ); assert.strictEqual( From c304c4acc3e1fc81d6ab8a883d6e66ac86ceb748 Mon Sep 17 00:00:00 2001 From: wellwelwel <46850407+wellwelwel@users.noreply.github.com> Date: Sat, 13 Apr 2024 07:39:01 -0300 Subject: [PATCH 2/7] refactor: simplify prototype validation --- lib/helpers.js | 49 ++++++------------- lib/parsers/binary_parser.js | 18 ++++--- lib/parsers/text_parser.js | 20 ++++---- .../execute-results-creation.test.mjs} | 40 ++++++--------- .../parsers/query-results-creation.test.mjs} | 40 ++++++--------- .../unit/helpers/create-safe-object.test.mjs | 20 -------- .../unit/helpers/native-object-props.test.mjs | 23 +++++++++ .../ensure-safe-binary-fields.test.mjs | 22 +++++++++ .../parsers/ensure-safe-text-fields.test.mjs | 22 +++++++++ ...ng-term-ensure-safe-binary-fields.test.mjs | 28 +++++++++++ ...long-term-ensure-safe-text-fields.test.mjs | 25 ++++++++++ 11 files changed, 189 insertions(+), 118 deletions(-) rename test/esm/{unit/parsers/prototype-binary-results.test.mjs => integration/parsers/execute-results-creation.test.mjs} (52%) rename test/esm/{unit/parsers/prototype-text-results.test.mjs => integration/parsers/query-results-creation.test.mjs} (52%) delete mode 100644 test/esm/unit/helpers/create-safe-object.test.mjs create mode 100644 test/esm/unit/helpers/native-object-props.test.mjs create mode 100644 test/esm/unit/parsers/ensure-safe-binary-fields.test.mjs create mode 100644 test/esm/unit/parsers/ensure-safe-text-fields.test.mjs create mode 100644 test/esm/unit/parsers/long-term-ensure-safe-binary-fields.test.mjs create mode 100644 test/esm/unit/parsers/long-term-ensure-safe-text-fields.test.mjs diff --git a/lib/helpers.js b/lib/helpers.js index 27b87121d7..75a0924747 100644 --- a/lib/helpers.js +++ b/lib/helpers.js @@ -64,36 +64,19 @@ function typeMatch(type, list, Types) { exports.typeMatch = typeMatch; -function createSafeObject() { - const nativeProps = ['hasOwnProperty', 'toString', 'valueOf']; - - const handler = { - get(_, prop, receiver) { - const isNativeProp = nativeProps.includes(prop); - - if (isNativeProp) { - return (...args) => Object.prototype[prop].apply(receiver, args); - } - - if (prop === '__proto__') { - return Object.prototype; - } - - return Reflect.get(...arguments); - }, - set(_, prop) { - const isNativeProp = nativeProps.includes(prop); - - if (isNativeProp || prop === '__proto__') { - return false; - } - - return Reflect.set(...arguments); - }, - }; - - const safePrototype = Object.create(Object.prototype); - return new Proxy(safePrototype, handler); -} - -exports.createSafeObject = createSafeObject; +const nativeObjectProps = [ + '__defineGetter__', + '__defineSetter__', + '__lookupGetter__', + '__lookupSetter__', + '__proto__', + 'constructor', + 'hasOwnProperty', + 'isPrototypeOf', + 'propertyIsEnumerable', + 'toLocaleString', + 'toString', + 'valueOf', +]; + +exports.nativeObjectProps = nativeObjectProps; diff --git a/lib/parsers/binary_parser.js b/lib/parsers/binary_parser.js index 2c4debc500..c36e154274 100644 --- a/lib/parsers/binary_parser.js +++ b/lib/parsers/binary_parser.js @@ -122,7 +122,7 @@ function compile(fields, options, config) { if (options.rowsAsArray) { parserFn(`const result = new Array(${fields.length});`); } else { - parserFn('const result = createSafeObject();'); + parserFn('const result = {};'); } // Global typeCast @@ -146,6 +146,13 @@ function compile(fields, options, config) { for (let i = 0; i < fields.length; i++) { fieldName = helpers.srcEscape(fields[i].name); + + if (helpers.nativeObjectProps.includes(fields[i].name)) { + throw new Error( + `The field name (${fieldName}) cannot be the same as the property of a native object.`, + ); + } + parserFn(`// ${fieldName}: ${typeNames[fields[i].columnType]}`); if (typeof options.nestTables === 'string') { @@ -154,9 +161,7 @@ function compile(fields, options, config) { )}]`; } else if (options.nestTables === true) { tableName = helpers.srcEscape(fields[i].table); - parserFn( - `if (!result[${tableName}]) result[${tableName}] = createSafeObject();`, - ); + parserFn(`if (!result[${tableName}]) result[${tableName}] = {};`); lvalue = `result[${tableName}][${fieldName}]`; } else if (options.rowsAsArray) { lvalue = `result[${i.toString(10)}]`; @@ -201,10 +206,7 @@ function compile(fields, options, config) { parserFn.toString(), ); } - return parserFn.toFunction({ - wrap, - createSafeObject: helpers.createSafeObject, - }); + return parserFn.toFunction({ wrap }); } function getBinaryParser(fields, options, config) { diff --git a/lib/parsers/text_parser.js b/lib/parsers/text_parser.js index 28d9132f8f..4c1aff2efe 100644 --- a/lib/parsers/text_parser.js +++ b/lib/parsers/text_parser.js @@ -131,7 +131,7 @@ function compile(fields, options, config) { if (options.rowsAsArray) { parserFn(`const result = new Array(${fields.length});`); } else { - parserFn('const result = createSafeObject();'); + parserFn('const result = {};'); } const resultTables = {}; @@ -143,9 +143,7 @@ function compile(fields, options, config) { } resultTablesArray = Object.keys(resultTables); for (let i = 0; i < resultTablesArray.length; i++) { - parserFn( - `result[${helpers.srcEscape(resultTablesArray[i])}] = createSafeObject();`, - ); + parserFn(`result[${helpers.srcEscape(resultTablesArray[i])}] = {};`); } } @@ -153,6 +151,13 @@ function compile(fields, options, config) { let fieldName = ''; for (let i = 0; i < fields.length; i++) { fieldName = helpers.srcEscape(fields[i].name); + + if (helpers.nativeObjectProps.includes(fields[i].name)) { + throw new Error( + `The field name (${fieldName}) cannot be the same as the property of a native object.`, + ); + } + parserFn(`// ${fieldName}: ${typeNames[fields[i].columnType]}`); if (typeof options.nestTables === 'string') { lvalue = `result[${helpers.srcEscape( @@ -197,12 +202,9 @@ function compile(fields, options, config) { ); } if (typeof options.typeCast === 'function') { - return parserFn.toFunction({ - wrap, - createSafeObject: helpers.createSafeObject, - }); + return parserFn.toFunction({ wrap }); } - return parserFn.toFunction({ createSafeObject: helpers.createSafeObject }); + return parserFn.toFunction(); } function getTextParser(fields, options, config) { diff --git a/test/esm/unit/parsers/prototype-binary-results.test.mjs b/test/esm/integration/parsers/execute-results-creation.test.mjs similarity index 52% rename from test/esm/unit/parsers/prototype-binary-results.test.mjs rename to test/esm/integration/parsers/execute-results-creation.test.mjs index 21268822e7..829e69cb04 100644 --- a/test/esm/unit/parsers/prototype-binary-results.test.mjs +++ b/test/esm/integration/parsers/execute-results-creation.test.mjs @@ -3,7 +3,7 @@ import { createConnection, describeOptions } from '../../../common.test.cjs'; const connection = createConnection().promise(); -describe('Binary Parser: Prototype Sanitization', describeOptions); +describe('Execute: Results Creation', describeOptions); Promise.all([ test(async () => { @@ -12,36 +12,28 @@ Promise.all([ test: 2, }, ]; + const emptyObject = {}; + const proto = Object.getPrototypeOf(emptyObject); + const nativeObjectProps = Object.getOwnPropertyNames(proto); const [results] = await connection.execute('SELECT 1+1 AS `test`'); - assert.deepStrictEqual(results, expected, 'Ensure clean object "results"'); + assert.deepStrictEqual(results, expected, 'Ensure exact object "results"'); assert.deepStrictEqual( - JSON.stringify(Object.getPrototypeOf(results[0])), - JSON.stringify({}), - 'Ensure clean properties in results items', - ); - assert.strictEqual( - typeof results[0].toString, - 'function', - 'Re-check prototypes (manually) in results columns', + Object.getOwnPropertyNames(results[0]), + Object.getOwnPropertyNames(expected[0]), + 'Deep ensure exact object "results"', ); - assert.strictEqual( - typeof results[0].test.toString, - 'function', - 'Ensure that the end-user is able to use prototypes', - ); - assert.strictEqual( - results[0].test.toString(), - '2', - 'Ensure that the end-user is able to use prototypes (manually): toString', - ); - assert.strictEqual( - results[0].test.toFixed(2), - '2.00', - 'Ensure that the end-user is able to use prototypes (manually): toFixed', + assert.deepStrictEqual( + Object.getPrototypeOf(results[0]), + Object.getPrototypeOf({}), + 'Ensure clean properties in results items', ); + nativeObjectProps.forEach((prop) => { + assert(prop in results[0], `Ensure ${prop} exists`); + }); + results[0].customProp = true; assert.strictEqual( results[0].customProp, diff --git a/test/esm/unit/parsers/prototype-text-results.test.mjs b/test/esm/integration/parsers/query-results-creation.test.mjs similarity index 52% rename from test/esm/unit/parsers/prototype-text-results.test.mjs rename to test/esm/integration/parsers/query-results-creation.test.mjs index ee25574c30..d512a53d8c 100644 --- a/test/esm/unit/parsers/prototype-text-results.test.mjs +++ b/test/esm/integration/parsers/query-results-creation.test.mjs @@ -3,7 +3,7 @@ import { createConnection, describeOptions } from '../../../common.test.cjs'; const connection = createConnection().promise(); -describe('Binary Parser: Prototype Sanitization', describeOptions); +describe('Query: Results Creation', describeOptions); Promise.all([ test(async () => { @@ -12,36 +12,28 @@ Promise.all([ test: 2, }, ]; + const emptyObject = {}; + const proto = Object.getPrototypeOf(emptyObject); + const nativeObjectProps = Object.getOwnPropertyNames(proto); const [results] = await connection.query('SELECT 1+1 AS `test`'); - assert.deepStrictEqual(results, expected, 'Ensure clean object "results"'); + assert.deepStrictEqual(results, expected, 'Ensure exact object "results"'); assert.deepStrictEqual( - JSON.stringify(Object.getPrototypeOf(results[0])), - JSON.stringify({}), - 'Ensure clean properties in results items', - ); - assert.strictEqual( - typeof results[0].toString, - 'function', - 'Re-check prototypes (manually) in results columns', + Object.getOwnPropertyNames(results[0]), + Object.getOwnPropertyNames(expected[0]), + 'Deep ensure exact object "results"', ); - assert.strictEqual( - typeof results[0].test.toString, - 'function', - 'Ensure that the end-user is able to use prototypes', - ); - assert.strictEqual( - results[0].test.toString(), - '2', - 'Ensure that the end-user is able to use prototypes (manually): toString', - ); - assert.strictEqual( - results[0].test.toFixed(2), - '2.00', - 'Ensure that the end-user is able to use prototypes (manually): toFixed', + assert.deepStrictEqual( + Object.getPrototypeOf(results[0]), + Object.getPrototypeOf({}), + 'Ensure clean properties in results items', ); + nativeObjectProps.forEach((prop) => { + assert(prop in results[0], `Ensure ${prop} exists`); + }); + results[0].customProp = true; assert.strictEqual( results[0].customProp, diff --git a/test/esm/unit/helpers/create-safe-object.test.mjs b/test/esm/unit/helpers/create-safe-object.test.mjs deleted file mode 100644 index 8a067617ee..0000000000 --- a/test/esm/unit/helpers/create-safe-object.test.mjs +++ /dev/null @@ -1,20 +0,0 @@ -import { describe, assert } from 'poku'; -import { describeOptions } from '../../../common.test.cjs'; -import { createSafeObject } from '../../../../lib/helpers.js'; - -describe('Creating a safe object', describeOptions); - -const stdObj = {}; -const safeObj = createSafeObject(); - -assert.deepStrictEqual(stdObj, safeObj, 'Ensure __proto__ is immutable'); -assert.throws(() => { - safeObj.__proto__ = { toString: () => true }; -}, 'Ensure safeObject is valid'); - -stdObj.__proto__ = { toString: () => true }; -assert.notDeepStrictEqual( - stdObj, - safeObj, - 'Ensure that the object is not the same as the poisoned __proto__', -); diff --git a/test/esm/unit/helpers/native-object-props.test.mjs b/test/esm/unit/helpers/native-object-props.test.mjs new file mode 100644 index 0000000000..91ce4c72d5 --- /dev/null +++ b/test/esm/unit/helpers/native-object-props.test.mjs @@ -0,0 +1,23 @@ +import { describe, assert } from 'poku'; +import { describeOptions } from '../../../common.test.cjs'; +import { nativeObjectProps } from '../../../../lib/helpers.js'; + +describe( + 'Checking long-term object properties along Node.js versions', + describeOptions, +); + +const emptyObject = {}; +const proto = Object.getPrototypeOf(emptyObject); +const expected = Object.getOwnPropertyNames(proto).sort(); + +assert.strictEqual( + nativeObjectProps.length, + expected.length, + 'Ensure objects have the same length', +); +assert.deepStrictEqual( + nativeObjectProps, + expected, + 'Ensure long term object properties', +); diff --git a/test/esm/unit/parsers/ensure-safe-binary-fields.test.mjs b/test/esm/unit/parsers/ensure-safe-binary-fields.test.mjs new file mode 100644 index 0000000000..258e78353a --- /dev/null +++ b/test/esm/unit/parsers/ensure-safe-binary-fields.test.mjs @@ -0,0 +1,22 @@ +import { describe, assert } from 'poku'; +import { describeOptions } from '../../../common.test.cjs'; +import getBinaryParser from '../../../../lib/parsers/binary_parser.js'; +import { srcEscape } from '../../../../lib/helpers.js'; +import { nativeObjectProps } from '../../../../lib/helpers.js'; + +describe('Binary Parser: Block Native Object Props', describeOptions); + +const blockedFields = nativeObjectProps.map((prop) => [{ name: prop }]); + +blockedFields.forEach((fields) => { + try { + getBinaryParser(fields, {}, {}); + assert.fail('An error were expected'); + } catch (error) { + assert.strictEqual( + error.message, + `The field name (${srcEscape(fields[0].name)}) cannot be the same as the property of a native object.`, + `Ensure safe ${fields[0].name}`, + ); + } +}); diff --git a/test/esm/unit/parsers/ensure-safe-text-fields.test.mjs b/test/esm/unit/parsers/ensure-safe-text-fields.test.mjs new file mode 100644 index 0000000000..3f1c64f590 --- /dev/null +++ b/test/esm/unit/parsers/ensure-safe-text-fields.test.mjs @@ -0,0 +1,22 @@ +import { describe, assert } from 'poku'; +import { describeOptions } from '../../../common.test.cjs'; +import TextRowParser from '../../../../lib/parsers/text_parser.js'; +import { srcEscape } from '../../../../lib/helpers.js'; +import { nativeObjectProps } from '../../../../lib/helpers.js'; + +describe('Text Parser: Block Native Object Props', describeOptions); + +const blockedFields = nativeObjectProps.map((prop) => [{ name: prop }]); + +blockedFields.forEach((fields) => { + try { + TextRowParser(fields, {}, {}); + assert.fail('An error were expected'); + } catch (error) { + assert.strictEqual( + error.message, + `The field name (${srcEscape(fields[0].name)}) cannot be the same as the property of a native object.`, + `Ensure safe ${fields[0].name}`, + ); + } +}); diff --git a/test/esm/unit/parsers/long-term-ensure-safe-binary-fields.test.mjs b/test/esm/unit/parsers/long-term-ensure-safe-binary-fields.test.mjs new file mode 100644 index 0000000000..09e518a84a --- /dev/null +++ b/test/esm/unit/parsers/long-term-ensure-safe-binary-fields.test.mjs @@ -0,0 +1,28 @@ +import { describe, assert } from 'poku'; +import { describeOptions } from '../../../common.test.cjs'; +import getBinaryParser from '../../../../lib/parsers/binary_parser.js'; +import { srcEscape } from '../../../../lib/helpers.js'; + +describe( + 'Binary Parser (Long Term): Block Native Object Props', + describeOptions, +); + +const emptyObject = {}; +const proto = Object.getPrototypeOf(emptyObject); +const nativeObjectProps = Object.getOwnPropertyNames(proto); + +const blockedFields = nativeObjectProps.map((prop) => [{ name: prop }]); + +blockedFields.forEach((fields) => { + try { + getBinaryParser(fields, {}, {}); + assert.fail('An error were expected'); + } catch (error) { + assert.strictEqual( + error.message, + `The field name (${srcEscape(fields[0].name)}) cannot be the same as the property of a native object.`, + `Ensure safe ${fields[0].name}`, + ); + } +}); diff --git a/test/esm/unit/parsers/long-term-ensure-safe-text-fields.test.mjs b/test/esm/unit/parsers/long-term-ensure-safe-text-fields.test.mjs new file mode 100644 index 0000000000..038687d069 --- /dev/null +++ b/test/esm/unit/parsers/long-term-ensure-safe-text-fields.test.mjs @@ -0,0 +1,25 @@ +import { describe, assert } from 'poku'; +import { describeOptions } from '../../../common.test.cjs'; +import TextRowParser from '../../../../lib/parsers/text_parser.js'; +import { srcEscape } from '../../../../lib/helpers.js'; + +describe('Text Parser (Long Term): Block Native Object Props', describeOptions); + +const emptyObject = {}; +const proto = Object.getPrototypeOf(emptyObject); +const nativeObjectProps = Object.getOwnPropertyNames(proto); + +const blockedFields = nativeObjectProps.map((prop) => [{ name: prop }]); + +blockedFields.forEach((fields) => { + try { + TextRowParser(fields, {}, {}); + assert.fail('An error were expected'); + } catch (error) { + assert.strictEqual( + error.message, + `The field name (${srcEscape(fields[0].name)}) cannot be the same as the property of a native object.`, + `Ensure safe ${fields[0].name}`, + ); + } +}); From a077f48d268c9f9cd6517781fa3093c75e1a9c3b Mon Sep 17 00:00:00 2001 From: wellwelwel <46850407+wellwelwel@users.noreply.github.com> Date: Sat, 13 Apr 2024 08:08:24 -0300 Subject: [PATCH 3/7] ci: fix typo --- test/esm/unit/parsers/ensure-safe-binary-fields.test.mjs | 2 +- test/esm/unit/parsers/ensure-safe-text-fields.test.mjs | 2 +- .../unit/parsers/long-term-ensure-safe-binary-fields.test.mjs | 2 +- .../esm/unit/parsers/long-term-ensure-safe-text-fields.test.mjs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/esm/unit/parsers/ensure-safe-binary-fields.test.mjs b/test/esm/unit/parsers/ensure-safe-binary-fields.test.mjs index 258e78353a..ee5bf49823 100644 --- a/test/esm/unit/parsers/ensure-safe-binary-fields.test.mjs +++ b/test/esm/unit/parsers/ensure-safe-binary-fields.test.mjs @@ -11,7 +11,7 @@ const blockedFields = nativeObjectProps.map((prop) => [{ name: prop }]); blockedFields.forEach((fields) => { try { getBinaryParser(fields, {}, {}); - assert.fail('An error were expected'); + assert.fail('An error was expected'); } catch (error) { assert.strictEqual( error.message, diff --git a/test/esm/unit/parsers/ensure-safe-text-fields.test.mjs b/test/esm/unit/parsers/ensure-safe-text-fields.test.mjs index 3f1c64f590..e882cd8268 100644 --- a/test/esm/unit/parsers/ensure-safe-text-fields.test.mjs +++ b/test/esm/unit/parsers/ensure-safe-text-fields.test.mjs @@ -11,7 +11,7 @@ const blockedFields = nativeObjectProps.map((prop) => [{ name: prop }]); blockedFields.forEach((fields) => { try { TextRowParser(fields, {}, {}); - assert.fail('An error were expected'); + assert.fail('An error was expected'); } catch (error) { assert.strictEqual( error.message, diff --git a/test/esm/unit/parsers/long-term-ensure-safe-binary-fields.test.mjs b/test/esm/unit/parsers/long-term-ensure-safe-binary-fields.test.mjs index 09e518a84a..3488db59a1 100644 --- a/test/esm/unit/parsers/long-term-ensure-safe-binary-fields.test.mjs +++ b/test/esm/unit/parsers/long-term-ensure-safe-binary-fields.test.mjs @@ -17,7 +17,7 @@ const blockedFields = nativeObjectProps.map((prop) => [{ name: prop }]); blockedFields.forEach((fields) => { try { getBinaryParser(fields, {}, {}); - assert.fail('An error were expected'); + assert.fail('An error was expected'); } catch (error) { assert.strictEqual( error.message, diff --git a/test/esm/unit/parsers/long-term-ensure-safe-text-fields.test.mjs b/test/esm/unit/parsers/long-term-ensure-safe-text-fields.test.mjs index 038687d069..32608a0ea5 100644 --- a/test/esm/unit/parsers/long-term-ensure-safe-text-fields.test.mjs +++ b/test/esm/unit/parsers/long-term-ensure-safe-text-fields.test.mjs @@ -14,7 +14,7 @@ const blockedFields = nativeObjectProps.map((prop) => [{ name: prop }]); blockedFields.forEach((fields) => { try { TextRowParser(fields, {}, {}); - assert.fail('An error were expected'); + assert.fail('An error was expected'); } catch (error) { assert.strictEqual( error.message, From bcaa661e7e2a1071950a95276f0142d909d8dd9f Mon Sep 17 00:00:00 2001 From: wellwelwel <46850407+wellwelwel@users.noreply.github.com> Date: Mon, 15 Apr 2024 12:05:26 -0300 Subject: [PATCH 4/7] chore: improve performance --- lib/helpers.js | 4 ++-- lib/parsers/binary_parser.js | 2 +- lib/parsers/text_parser.js | 2 +- test/esm/unit/helpers/native-object-props.test.mjs | 4 ++-- test/esm/unit/parsers/ensure-safe-binary-fields.test.mjs | 2 +- test/esm/unit/parsers/ensure-safe-text-fields.test.mjs | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/helpers.js b/lib/helpers.js index 75a0924747..11dbd9076a 100644 --- a/lib/helpers.js +++ b/lib/helpers.js @@ -64,7 +64,7 @@ function typeMatch(type, list, Types) { exports.typeMatch = typeMatch; -const nativeObjectProps = [ +const nativeObjectProps = new Set([ '__defineGetter__', '__defineSetter__', '__lookupGetter__', @@ -77,6 +77,6 @@ const nativeObjectProps = [ 'toLocaleString', 'toString', 'valueOf', -]; +]); exports.nativeObjectProps = nativeObjectProps; diff --git a/lib/parsers/binary_parser.js b/lib/parsers/binary_parser.js index c36e154274..27023a15db 100644 --- a/lib/parsers/binary_parser.js +++ b/lib/parsers/binary_parser.js @@ -147,7 +147,7 @@ function compile(fields, options, config) { for (let i = 0; i < fields.length; i++) { fieldName = helpers.srcEscape(fields[i].name); - if (helpers.nativeObjectProps.includes(fields[i].name)) { + if (helpers.nativeObjectProps.has(fields[i].name)) { throw new Error( `The field name (${fieldName}) cannot be the same as the property of a native object.`, ); diff --git a/lib/parsers/text_parser.js b/lib/parsers/text_parser.js index 4c1aff2efe..be2290dbb2 100644 --- a/lib/parsers/text_parser.js +++ b/lib/parsers/text_parser.js @@ -152,7 +152,7 @@ function compile(fields, options, config) { for (let i = 0; i < fields.length; i++) { fieldName = helpers.srcEscape(fields[i].name); - if (helpers.nativeObjectProps.includes(fields[i].name)) { + if (helpers.nativeObjectProps.has(fields[i].name)) { throw new Error( `The field name (${fieldName}) cannot be the same as the property of a native object.`, ); diff --git a/test/esm/unit/helpers/native-object-props.test.mjs b/test/esm/unit/helpers/native-object-props.test.mjs index 91ce4c72d5..47ab804844 100644 --- a/test/esm/unit/helpers/native-object-props.test.mjs +++ b/test/esm/unit/helpers/native-object-props.test.mjs @@ -12,12 +12,12 @@ const proto = Object.getPrototypeOf(emptyObject); const expected = Object.getOwnPropertyNames(proto).sort(); assert.strictEqual( - nativeObjectProps.length, + nativeObjectProps.size, expected.length, 'Ensure objects have the same length', ); assert.deepStrictEqual( - nativeObjectProps, + Array.from(nativeObjectProps).sort(), expected, 'Ensure long term object properties', ); diff --git a/test/esm/unit/parsers/ensure-safe-binary-fields.test.mjs b/test/esm/unit/parsers/ensure-safe-binary-fields.test.mjs index ee5bf49823..78c6273fd0 100644 --- a/test/esm/unit/parsers/ensure-safe-binary-fields.test.mjs +++ b/test/esm/unit/parsers/ensure-safe-binary-fields.test.mjs @@ -6,7 +6,7 @@ import { nativeObjectProps } from '../../../../lib/helpers.js'; describe('Binary Parser: Block Native Object Props', describeOptions); -const blockedFields = nativeObjectProps.map((prop) => [{ name: prop }]); +const blockedFields = Array.from(nativeObjectProps).map((prop) => [{ name: prop }]); blockedFields.forEach((fields) => { try { diff --git a/test/esm/unit/parsers/ensure-safe-text-fields.test.mjs b/test/esm/unit/parsers/ensure-safe-text-fields.test.mjs index e882cd8268..fbac9ccb5c 100644 --- a/test/esm/unit/parsers/ensure-safe-text-fields.test.mjs +++ b/test/esm/unit/parsers/ensure-safe-text-fields.test.mjs @@ -6,7 +6,7 @@ import { nativeObjectProps } from '../../../../lib/helpers.js'; describe('Text Parser: Block Native Object Props', describeOptions); -const blockedFields = nativeObjectProps.map((prop) => [{ name: prop }]); +const blockedFields = Array.from(nativeObjectProps).map((prop) => [{ name: prop }]); blockedFields.forEach((fields) => { try { From e3667e3b6ea5654c05e465b1946e27a7680fc314 Mon Sep 17 00:00:00 2001 From: wellwelwel <46850407+wellwelwel@users.noreply.github.com> Date: Mon, 15 Apr 2024 12:10:54 -0300 Subject: [PATCH 5/7] chore: fix lint --- test/esm/unit/parsers/ensure-safe-binary-fields.test.mjs | 4 +++- test/esm/unit/parsers/ensure-safe-text-fields.test.mjs | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/test/esm/unit/parsers/ensure-safe-binary-fields.test.mjs b/test/esm/unit/parsers/ensure-safe-binary-fields.test.mjs index 78c6273fd0..db8c967bd9 100644 --- a/test/esm/unit/parsers/ensure-safe-binary-fields.test.mjs +++ b/test/esm/unit/parsers/ensure-safe-binary-fields.test.mjs @@ -6,7 +6,9 @@ import { nativeObjectProps } from '../../../../lib/helpers.js'; describe('Binary Parser: Block Native Object Props', describeOptions); -const blockedFields = Array.from(nativeObjectProps).map((prop) => [{ name: prop }]); +const blockedFields = Array.from(nativeObjectProps).map((prop) => [ + { name: prop }, +]); blockedFields.forEach((fields) => { try { diff --git a/test/esm/unit/parsers/ensure-safe-text-fields.test.mjs b/test/esm/unit/parsers/ensure-safe-text-fields.test.mjs index fbac9ccb5c..65329d1b2d 100644 --- a/test/esm/unit/parsers/ensure-safe-text-fields.test.mjs +++ b/test/esm/unit/parsers/ensure-safe-text-fields.test.mjs @@ -6,7 +6,9 @@ import { nativeObjectProps } from '../../../../lib/helpers.js'; describe('Text Parser: Block Native Object Props', describeOptions); -const blockedFields = Array.from(nativeObjectProps).map((prop) => [{ name: prop }]); +const blockedFields = Array.from(nativeObjectProps).map((prop) => [ + { name: prop }, +]); blockedFields.forEach((fields) => { try { From c895d3a290105398af106217cb96b65e39fefa38 Mon Sep 17 00:00:00 2001 From: wellwelwel <46850407+wellwelwel@users.noreply.github.com> Date: Wed, 17 Apr 2024 06:25:43 -0300 Subject: [PATCH 6/7] chore: change from `nativeObjectProps` to `privateObjectProps` --- lib/helpers.js | 11 ++------ lib/parsers/binary_parser.js | 2 +- lib/parsers/text_parser.js | 2 +- .../parsers/execute-results-creation.test.mjs | 4 +-- .../parsers/query-results-creation.test.mjs | 4 +-- .../unit/helpers/native-object-props.test.mjs | 23 --------------- .../ensure-safe-binary-fields.test.mjs | 4 +-- .../parsers/ensure-safe-text-fields.test.mjs | 4 +-- ...ng-term-ensure-safe-binary-fields.test.mjs | 28 ------------------- ...long-term-ensure-safe-text-fields.test.mjs | 25 ----------------- 10 files changed, 12 insertions(+), 95 deletions(-) delete mode 100644 test/esm/unit/helpers/native-object-props.test.mjs delete mode 100644 test/esm/unit/parsers/long-term-ensure-safe-binary-fields.test.mjs delete mode 100644 test/esm/unit/parsers/long-term-ensure-safe-text-fields.test.mjs diff --git a/lib/helpers.js b/lib/helpers.js index 11dbd9076a..fdba2ddb76 100644 --- a/lib/helpers.js +++ b/lib/helpers.js @@ -64,19 +64,12 @@ function typeMatch(type, list, Types) { exports.typeMatch = typeMatch; -const nativeObjectProps = new Set([ +const privateObjectProps = new Set([ '__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__', '__proto__', - 'constructor', - 'hasOwnProperty', - 'isPrototypeOf', - 'propertyIsEnumerable', - 'toLocaleString', - 'toString', - 'valueOf', ]); -exports.nativeObjectProps = nativeObjectProps; +exports.privateObjectProps = privateObjectProps; diff --git a/lib/parsers/binary_parser.js b/lib/parsers/binary_parser.js index 27023a15db..f7be14dda6 100644 --- a/lib/parsers/binary_parser.js +++ b/lib/parsers/binary_parser.js @@ -147,7 +147,7 @@ function compile(fields, options, config) { for (let i = 0; i < fields.length; i++) { fieldName = helpers.srcEscape(fields[i].name); - if (helpers.nativeObjectProps.has(fields[i].name)) { + if (helpers.privateObjectProps.has(fields[i].name)) { throw new Error( `The field name (${fieldName}) cannot be the same as the property of a native object.`, ); diff --git a/lib/parsers/text_parser.js b/lib/parsers/text_parser.js index be2290dbb2..d355a264f5 100644 --- a/lib/parsers/text_parser.js +++ b/lib/parsers/text_parser.js @@ -152,7 +152,7 @@ function compile(fields, options, config) { for (let i = 0; i < fields.length; i++) { fieldName = helpers.srcEscape(fields[i].name); - if (helpers.nativeObjectProps.has(fields[i].name)) { + if (helpers.privateObjectProps.has(fields[i].name)) { throw new Error( `The field name (${fieldName}) cannot be the same as the property of a native object.`, ); diff --git a/test/esm/integration/parsers/execute-results-creation.test.mjs b/test/esm/integration/parsers/execute-results-creation.test.mjs index 829e69cb04..b6296af2ea 100644 --- a/test/esm/integration/parsers/execute-results-creation.test.mjs +++ b/test/esm/integration/parsers/execute-results-creation.test.mjs @@ -14,7 +14,7 @@ Promise.all([ ]; const emptyObject = {}; const proto = Object.getPrototypeOf(emptyObject); - const nativeObjectProps = Object.getOwnPropertyNames(proto); + const privateObjectProps = Object.getOwnPropertyNames(proto); const [results] = await connection.execute('SELECT 1+1 AS `test`'); @@ -30,7 +30,7 @@ Promise.all([ 'Ensure clean properties in results items', ); - nativeObjectProps.forEach((prop) => { + privateObjectProps.forEach((prop) => { assert(prop in results[0], `Ensure ${prop} exists`); }); diff --git a/test/esm/integration/parsers/query-results-creation.test.mjs b/test/esm/integration/parsers/query-results-creation.test.mjs index d512a53d8c..030c33dad1 100644 --- a/test/esm/integration/parsers/query-results-creation.test.mjs +++ b/test/esm/integration/parsers/query-results-creation.test.mjs @@ -14,7 +14,7 @@ Promise.all([ ]; const emptyObject = {}; const proto = Object.getPrototypeOf(emptyObject); - const nativeObjectProps = Object.getOwnPropertyNames(proto); + const privateObjectProps = Object.getOwnPropertyNames(proto); const [results] = await connection.query('SELECT 1+1 AS `test`'); @@ -30,7 +30,7 @@ Promise.all([ 'Ensure clean properties in results items', ); - nativeObjectProps.forEach((prop) => { + privateObjectProps.forEach((prop) => { assert(prop in results[0], `Ensure ${prop} exists`); }); diff --git a/test/esm/unit/helpers/native-object-props.test.mjs b/test/esm/unit/helpers/native-object-props.test.mjs deleted file mode 100644 index 47ab804844..0000000000 --- a/test/esm/unit/helpers/native-object-props.test.mjs +++ /dev/null @@ -1,23 +0,0 @@ -import { describe, assert } from 'poku'; -import { describeOptions } from '../../../common.test.cjs'; -import { nativeObjectProps } from '../../../../lib/helpers.js'; - -describe( - 'Checking long-term object properties along Node.js versions', - describeOptions, -); - -const emptyObject = {}; -const proto = Object.getPrototypeOf(emptyObject); -const expected = Object.getOwnPropertyNames(proto).sort(); - -assert.strictEqual( - nativeObjectProps.size, - expected.length, - 'Ensure objects have the same length', -); -assert.deepStrictEqual( - Array.from(nativeObjectProps).sort(), - expected, - 'Ensure long term object properties', -); diff --git a/test/esm/unit/parsers/ensure-safe-binary-fields.test.mjs b/test/esm/unit/parsers/ensure-safe-binary-fields.test.mjs index db8c967bd9..f4dff57ae5 100644 --- a/test/esm/unit/parsers/ensure-safe-binary-fields.test.mjs +++ b/test/esm/unit/parsers/ensure-safe-binary-fields.test.mjs @@ -2,11 +2,11 @@ import { describe, assert } from 'poku'; import { describeOptions } from '../../../common.test.cjs'; import getBinaryParser from '../../../../lib/parsers/binary_parser.js'; import { srcEscape } from '../../../../lib/helpers.js'; -import { nativeObjectProps } from '../../../../lib/helpers.js'; +import { privateObjectProps } from '../../../../lib/helpers.js'; describe('Binary Parser: Block Native Object Props', describeOptions); -const blockedFields = Array.from(nativeObjectProps).map((prop) => [ +const blockedFields = Array.from(privateObjectProps).map((prop) => [ { name: prop }, ]); diff --git a/test/esm/unit/parsers/ensure-safe-text-fields.test.mjs b/test/esm/unit/parsers/ensure-safe-text-fields.test.mjs index 65329d1b2d..8fd569f9d5 100644 --- a/test/esm/unit/parsers/ensure-safe-text-fields.test.mjs +++ b/test/esm/unit/parsers/ensure-safe-text-fields.test.mjs @@ -2,11 +2,11 @@ import { describe, assert } from 'poku'; import { describeOptions } from '../../../common.test.cjs'; import TextRowParser from '../../../../lib/parsers/text_parser.js'; import { srcEscape } from '../../../../lib/helpers.js'; -import { nativeObjectProps } from '../../../../lib/helpers.js'; +import { privateObjectProps } from '../../../../lib/helpers.js'; describe('Text Parser: Block Native Object Props', describeOptions); -const blockedFields = Array.from(nativeObjectProps).map((prop) => [ +const blockedFields = Array.from(privateObjectProps).map((prop) => [ { name: prop }, ]); diff --git a/test/esm/unit/parsers/long-term-ensure-safe-binary-fields.test.mjs b/test/esm/unit/parsers/long-term-ensure-safe-binary-fields.test.mjs deleted file mode 100644 index 3488db59a1..0000000000 --- a/test/esm/unit/parsers/long-term-ensure-safe-binary-fields.test.mjs +++ /dev/null @@ -1,28 +0,0 @@ -import { describe, assert } from 'poku'; -import { describeOptions } from '../../../common.test.cjs'; -import getBinaryParser from '../../../../lib/parsers/binary_parser.js'; -import { srcEscape } from '../../../../lib/helpers.js'; - -describe( - 'Binary Parser (Long Term): Block Native Object Props', - describeOptions, -); - -const emptyObject = {}; -const proto = Object.getPrototypeOf(emptyObject); -const nativeObjectProps = Object.getOwnPropertyNames(proto); - -const blockedFields = nativeObjectProps.map((prop) => [{ name: prop }]); - -blockedFields.forEach((fields) => { - try { - getBinaryParser(fields, {}, {}); - assert.fail('An error was expected'); - } catch (error) { - assert.strictEqual( - error.message, - `The field name (${srcEscape(fields[0].name)}) cannot be the same as the property of a native object.`, - `Ensure safe ${fields[0].name}`, - ); - } -}); diff --git a/test/esm/unit/parsers/long-term-ensure-safe-text-fields.test.mjs b/test/esm/unit/parsers/long-term-ensure-safe-text-fields.test.mjs deleted file mode 100644 index 32608a0ea5..0000000000 --- a/test/esm/unit/parsers/long-term-ensure-safe-text-fields.test.mjs +++ /dev/null @@ -1,25 +0,0 @@ -import { describe, assert } from 'poku'; -import { describeOptions } from '../../../common.test.cjs'; -import TextRowParser from '../../../../lib/parsers/text_parser.js'; -import { srcEscape } from '../../../../lib/helpers.js'; - -describe('Text Parser (Long Term): Block Native Object Props', describeOptions); - -const emptyObject = {}; -const proto = Object.getPrototypeOf(emptyObject); -const nativeObjectProps = Object.getOwnPropertyNames(proto); - -const blockedFields = nativeObjectProps.map((prop) => [{ name: prop }]); - -blockedFields.forEach((fields) => { - try { - TextRowParser(fields, {}, {}); - assert.fail('An error was expected'); - } catch (error) { - assert.strictEqual( - error.message, - `The field name (${srcEscape(fields[0].name)}) cannot be the same as the property of a native object.`, - `Ensure safe ${fields[0].name}`, - ); - } -}); From a866100e4a3198d16e95006727e1f9a984a6f588 Mon Sep 17 00:00:00 2001 From: wellwelwel <46850407+wellwelwel@users.noreply.github.com> Date: Wed, 17 Apr 2024 06:53:41 -0300 Subject: [PATCH 7/7] chore: improve error message --- lib/parsers/binary_parser.js | 2 +- lib/parsers/text_parser.js | 2 +- test/esm/unit/parsers/ensure-safe-binary-fields.test.mjs | 2 +- test/esm/unit/parsers/ensure-safe-text-fields.test.mjs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/parsers/binary_parser.js b/lib/parsers/binary_parser.js index f7be14dda6..5a08df7b7c 100644 --- a/lib/parsers/binary_parser.js +++ b/lib/parsers/binary_parser.js @@ -149,7 +149,7 @@ function compile(fields, options, config) { if (helpers.privateObjectProps.has(fields[i].name)) { throw new Error( - `The field name (${fieldName}) cannot be the same as the property of a native object.`, + `The field name (${fieldName}) can't be the same as an object's private property.`, ); } diff --git a/lib/parsers/text_parser.js b/lib/parsers/text_parser.js index d355a264f5..7e46514463 100644 --- a/lib/parsers/text_parser.js +++ b/lib/parsers/text_parser.js @@ -154,7 +154,7 @@ function compile(fields, options, config) { if (helpers.privateObjectProps.has(fields[i].name)) { throw new Error( - `The field name (${fieldName}) cannot be the same as the property of a native object.`, + `The field name (${fieldName}) can't be the same as an object's private property.`, ); } diff --git a/test/esm/unit/parsers/ensure-safe-binary-fields.test.mjs b/test/esm/unit/parsers/ensure-safe-binary-fields.test.mjs index f4dff57ae5..a16cc43014 100644 --- a/test/esm/unit/parsers/ensure-safe-binary-fields.test.mjs +++ b/test/esm/unit/parsers/ensure-safe-binary-fields.test.mjs @@ -17,7 +17,7 @@ blockedFields.forEach((fields) => { } catch (error) { assert.strictEqual( error.message, - `The field name (${srcEscape(fields[0].name)}) cannot be the same as the property of a native object.`, + `The field name (${srcEscape(fields[0].name)}) can't be the same as an object's private property.`, `Ensure safe ${fields[0].name}`, ); } diff --git a/test/esm/unit/parsers/ensure-safe-text-fields.test.mjs b/test/esm/unit/parsers/ensure-safe-text-fields.test.mjs index 8fd569f9d5..36ef7f4516 100644 --- a/test/esm/unit/parsers/ensure-safe-text-fields.test.mjs +++ b/test/esm/unit/parsers/ensure-safe-text-fields.test.mjs @@ -17,7 +17,7 @@ blockedFields.forEach((fields) => { } catch (error) { assert.strictEqual( error.message, - `The field name (${srcEscape(fields[0].name)}) cannot be the same as the property of a native object.`, + `The field name (${srcEscape(fields[0].name)}) can't be the same as an object's private property.`, `Ensure safe ${fields[0].name}`, ); }