Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #221 usage of new Function(...) for CSP #223

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Prev Previous commit
Next Next commit
Converts _createWriter in RecordType prototype chain
ajainarayanan committed Feb 24, 2019
commit d4d3f70a21630f138c7077fbb4f3fa681106b25c
54 changes: 29 additions & 25 deletions lib/types.js
Original file line number Diff line number Diff line change
@@ -2300,33 +2300,37 @@ RecordType.prototype._createSkipper = function () {
RecordType.prototype._createWriter = function () {
// jshint -W054
// We still do default handling here, in case a normal JS object is passed.
var args = [];
var name = this._getConstructorName();
var body = 'return function write' + name + '(t, v) {\n';

var values = [];
var i, l, field, value;
for (i = 0, l = this.fields.length; i < l; i++) {
field = this.fields[i];
args.push('t' + i);
var dValues = {};
this.fields.forEach((field, i) => {
values.push(field.type);
body += ' ';
if (field.defaultValue() === undefined) {
body += 't' + i + '._write(t, v.' + field.name + ');\n';
} else {
value = field.type.toBuffer(field.defaultValue()).toString('binary');
// Convert the default value to a binary string ahead of time. We aren't
// converting it to a buffer to avoid retaining too much memory. If we
// had our own buffer pool, this could be an idea in the future.
args.push('d' + i);
values.push(value);
body += 'var v' + i + ' = v.' + field.name + ';\n';
body += 'if (v' + i + ' === undefined) {\n';
body += ' t.writeBinary(d' + i + ', ' + value.length + ');\n';
body += ' } else {\n t' + i + '._write(t, v' + i + ');\n }\n';
}
}
body += '}';
return new Function(args.join(), body).apply(undefined, values);
if (field.defaultValue() !== undefined) {
dValues[i] = field.type.toBuffer(field.defaultValue()).toString('binary');
}
});
var self = this;
function ConstructorFunction(vv, dv) {
var constructorName = self._getConstructorName();
var innerFunction = ({
[constructorName]: function (t, v) {
for (var i=0, l = self.fields.length; i<l; i++) {
let f = self.fields[i];
if (f.defaultValue() === undefined) {
vv[i]._write(t, v[f.name]);
} else {
if (v[f.name] === undefined) {
t.writeBinary(dv[i], dv[i].length);
} else {
vv[i]._write(t, v[f.name]);
}
}
}
}
})[constructorName];
return innerFunction;
}
return ConstructorFunction(values, dValues);
};

RecordType.prototype._update = function (resolver, type, opts) {