Browse Source

Escape ampersand, less-than, and greater-than in attribute value (#6604)

release-v0.22.13
nanto_vi, TOYAMA Nao 5 months ago
committed by GitHub
parent
commit
3b1b9faaa6
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 14
      packages/core/src/dom_components/model/Component.ts
  2. 8
      packages/core/src/utils/mixins.ts
  3. 6
      packages/core/test/specs/dom_components/model/Component.ts

14
packages/core/src/dom_components/model/Component.ts

@ -11,7 +11,15 @@ import {
bindAll, bindAll,
keys, keys,
} from 'underscore'; } from 'underscore';
import { shallowDiff, capitalize, isEmptyObj, isObject, toLowerCase } from '../../utils/mixins'; import {
shallowDiff,
capitalize,
isEmptyObj,
isObject,
toLowerCase,
escapeAltQuoteAttrValue,
escapeAttrValue,
} from '../../utils/mixins';
import StyleableModel, { import StyleableModel, {
GetStyleOpts, GetStyleOpts,
StyleProps, StyleProps,
@ -1597,9 +1605,9 @@ export default class Component extends StyleableModel<ComponentProperties> {
} else { } else {
let valueRes = ''; let valueRes = '';
if (opts.altQuoteAttr && isString(val) && val.indexOf('"') >= 0) { if (opts.altQuoteAttr && isString(val) && val.indexOf('"') >= 0) {
valueRes = `'${val.replace(/'/g, '&apos;')}'`; valueRes = `'${escapeAltQuoteAttrValue(val)}'`;
} else { } else {
const value = isString(val) ? val.replace(/"/g, '&quot;') : val; const value = isString(val) ? escapeAttrValue(val) : val;
valueRes = `"${value}"`; valueRes = `"${value}"`;
} }

8
packages/core/src/utils/mixins.ts

@ -192,6 +192,14 @@ export const escapeNodeContent = (str = '') => {
return `${str}`.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;'); return `${str}`.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
}; };
export const escapeAttrValue = (str = '') => {
return `${str}`.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
};
export const escapeAltQuoteAttrValue = (str = '') => {
return `${str}`.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/'/g, '&apos;');
};
export const deepMerge = (...args: ObjectAny[]) => { export const deepMerge = (...args: ObjectAny[]) => {
const target = { ...args[0] }; const target = { ...args[0] };

6
packages/core/test/specs/dom_components/model/Component.ts

@ -155,7 +155,7 @@ describe('Component', () => {
obj.set({ obj.set({
bool: true, bool: true,
removable: false, removable: false,
string: 'st\'ri"ng', string: 'st\'ri"ng&<>',
array: [1, 'string', true], array: [1, 'string', true],
object: { a: 1, b: 'string', c: true }, object: { a: 1, b: 'string', c: true },
null: null, null: null,
@ -164,12 +164,12 @@ describe('Component', () => {
zero: 0, zero: 0,
_private: 'value', _private: 'value',
}); });
let resStr = "st'ri&quot;ng"; let resStr = "st'ri&quot;ng&amp;&lt;&gt;";
let resArr = '[1,&quot;string&quot;,true]'; let resArr = '[1,&quot;string&quot;,true]';
let resObj = '{&quot;a&quot;:1,&quot;b&quot;:&quot;string&quot;,&quot;c&quot;:true}'; let resObj = '{&quot;a&quot;:1,&quot;b&quot;:&quot;string&quot;,&quot;c&quot;:true}';
let res = `<div data-gjs-removable="false" data-gjs-bool="true" data-gjs-string="${resStr}" data-gjs-array="${resArr}" data-gjs-object="${resObj}" data-gjs-empty="" data-gjs-zero="0"></div>`; let res = `<div data-gjs-removable="false" data-gjs-bool="true" data-gjs-string="${resStr}" data-gjs-array="${resArr}" data-gjs-object="${resObj}" data-gjs-empty="" data-gjs-zero="0"></div>`;
expect(obj.toHTML({ withProps: true })).toEqual(res); expect(obj.toHTML({ withProps: true })).toEqual(res);
resStr = 'st&apos;ri"ng'; resStr = 'st&apos;ri"ng&amp;&lt;&gt;';
resArr = '[1,"string",true]'; resArr = '[1,"string",true]';
resObj = '{"a":1,"b":"string","c":true}'; resObj = '{"a":1,"b":"string","c":true}';
res = `<div data-gjs-removable="false" data-gjs-bool="true" data-gjs-string='${resStr}' data-gjs-array='${resArr}' data-gjs-object='${resObj}' data-gjs-empty="" data-gjs-zero="0"></div>`; res = `<div data-gjs-removable="false" data-gjs-bool="true" data-gjs-string='${resStr}' data-gjs-array='${resArr}' data-gjs-object='${resObj}' data-gjs-empty="" data-gjs-zero="0"></div>`;

Loading…
Cancel
Save