Skip to content

Commit 9ea36ba

Browse files
authored
Merge pull request #719 from jportner/frozen-prototype-fix
Make escapeXML work when the Function prototype is frozen
2 parents f818bce + 181a537 commit 9ea36ba

File tree

3 files changed

+39
-4
lines changed

3 files changed

+39
-4
lines changed

lib/utils.js

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,25 @@ exports.escapeXML = function (markup) {
9999
: String(markup)
100100
.replace(_MATCH_HTML, encode_char);
101101
};
102-
exports.escapeXML.toString = function () {
102+
103+
function escapeXMLToString() {
103104
return Function.prototype.toString.call(this) + ';\n' + escapeFuncStr;
104-
};
105+
}
106+
107+
try {
108+
if (typeof Object.defineProperty === 'function') {
109+
// If the Function prototype is frozen, the "toString" property is non-writable. This means that any objects which inherit this property
110+
// cannot have the property changed using an assignment. If using strict mode, attempting that will cause an error. If not using strict
111+
// mode, attempting that will be silently ignored.
112+
// However, we can still explicitly shadow the prototype's "toString" property by defining a new "toString" property on this object.
113+
Object.defineProperty(exports.escapeXML, 'toString', { value: escapeXMLToString });
114+
} else {
115+
// If Object.defineProperty() doesn't exist, attempt to shadow this property using the assignment operator.
116+
exports.escapeXML.toString = escapeXMLToString;
117+
}
118+
} catch (err) {
119+
console.warn('Unable to set escapeXML.toString (is the Function prototype frozen?)');
120+
}
105121

106122
/**
107123
* Naive copy of properties from one object to another.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,6 @@
3737
"node": ">=0.10.0"
3838
},
3939
"scripts": {
40-
"test": "mocha"
40+
"test": "mocha -u tdd"
4141
}
4242
}

test/utils.js

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,27 @@ suite('unit testing exported functions of module \'utils.js\'', function () {
8383
*/
8484
suite('unit testing function \'escapeXML\' of module \'utils.js\'', function () {
8585
test('it should be callable without parameters', function () {
86+
const stringified =
87+
`function (markup) {
88+
return markup == undefined
89+
? ''
90+
: String(markup)
91+
.replace(_MATCH_HTML, encode_char);
92+
};
93+
var _ENCODE_HTML_RULES = {
94+
"&": "&"
95+
, "<": "&lt;"
96+
, ">": "&gt;"
97+
, '"': "&#34;"
98+
, "'": "&#39;"
99+
}
100+
, _MATCH_HTML = /[&<>'"]/g;
101+
function encode_char(c) {
102+
return _ENCODE_HTML_RULES[c] || c;
103+
};
104+
`;
86105
assert.doesNotThrow(() => { utils.escapeXML.toString(); });
87-
assert.ok(typeof(utils.escapeXML.toString())==='string');
106+
assert.ok(utils.escapeXML.toString()===stringified);
88107
});
89108
});
90109

0 commit comments

Comments
 (0)