Changeset: Stricter validation checks

pull/5304/head
Richard Hansen 2021-11-27 02:35:58 -05:00
parent ad78b24113
commit 2608a81654
1 changed files with 15 additions and 14 deletions

View File

@ -296,7 +296,6 @@ exports.checkRep = (cs) => {
const assem = exports.smartOpAssembler(); const assem = exports.smartOpAssembler();
let oldPos = 0; let oldPos = 0;
let calcNewLen = 0; let calcNewLen = 0;
let numInserted = 0;
const iter = exports.opIterator(ops); const iter = exports.opIterator(ops);
while (iter.hasNext()) { while (iter.hasNext()) {
const o = iter.next(); const o = iter.next();
@ -311,25 +310,29 @@ exports.checkRep = (cs) => {
break; break;
case '+': case '+':
{ {
assert(charBank.length >= o.chars, 'Invalid changeset: not enough chars in charBank');
const chars = charBank.slice(0, o.chars);
const nlines = (chars.match(/\n/g) || []).length;
assert(nlines === o.lines,
'Invalid changeset: number of newlines in insert op does not match the charBank');
assert(o.lines === 0 || chars.endsWith('\n'),
'Invalid changeset: multiline insert op does not end with a newline');
charBank = charBank.slice(o.chars);
calcNewLen += o.chars; calcNewLen += o.chars;
numInserted += o.chars;
assert(calcNewLen <= newLen, `${calcNewLen} > ${newLen} in ${cs}`); assert(calcNewLen <= newLen, `${calcNewLen} > ${newLen} in ${cs}`);
break; break;
} }
default:
assert(false, `Invalid changeset: Unknown opcode: ${JSON.stringify(o.opcode)}`);
} }
assem.append(o); assem.append(o);
} }
calcNewLen += oldLen - oldPos; calcNewLen += oldLen - oldPos;
charBank = charBank.substring(0, numInserted); assert(calcNewLen === newLen, 'Invalid changeset: claimed length does not match actual length');
while (charBank.length < numInserted) { assert(charBank === '', 'Invalid changeset: excess characters in the charBank');
charBank += '?';
}
assem.endDocument(); assem.endDocument();
const normalized = exports.pack(oldLen, calcNewLen, assem.toString(), charBank); const normalized = exports.pack(oldLen, calcNewLen, assem.toString(), unpacked.charBank);
assert(normalized === cs, 'Invalid changeset (checkRep failed)'); assert(normalized === cs, 'Invalid changeset: not in canonical form');
return cs; return cs;
}; };
@ -998,9 +1001,7 @@ const applyZip = (in1, in2, func) => {
exports.unpack = (cs) => { exports.unpack = (cs) => {
const headerRegex = /Z:([0-9a-z]+)([><])([0-9a-z]+)|/; const headerRegex = /Z:([0-9a-z]+)([><])([0-9a-z]+)|/;
const headerMatch = headerRegex.exec(cs); const headerMatch = headerRegex.exec(cs);
if ((!headerMatch) || (!headerMatch[0])) { if ((!headerMatch) || (!headerMatch[0])) error(`Not a changeset: ${cs}`);
error(`Not a exports: ${cs}`);
}
const oldLen = exports.parseNum(headerMatch[1]); const oldLen = exports.parseNum(headerMatch[1]);
const changeSign = (headerMatch[2] === '>') ? 1 : -1; const changeSign = (headerMatch[2] === '>') ? 1 : -1;
const changeMag = exports.parseNum(headerMatch[3]); const changeMag = exports.parseNum(headerMatch[3]);