Remove placeholders from spec and implementations 3/5
Update JS implementation: remove placeholders; reject zero-length streamed binary chunks.
This commit is contained in:
parent
b5f4c3a498
commit
0b0709b615
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "preserves",
|
"name": "preserves",
|
||||||
"version": "0.2.0",
|
"version": "0.3.0",
|
||||||
"description": "Experimental data serialization format",
|
"description": "Experimental data serialization format",
|
||||||
"homepage": "https://gitlab.com/preserves/preserves",
|
"homepage": "https://gitlab.com/preserves/preserves",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
|
|
|
@ -28,7 +28,6 @@ class Decoder {
|
||||||
? (packet._view || packet) // strip off Bytes wrapper, if any
|
? (packet._view || packet) // strip off Bytes wrapper, if any
|
||||||
: new Uint8Array(0);
|
: new Uint8Array(0);
|
||||||
this.index = 0;
|
this.index = 0;
|
||||||
this.placeholders = fromJS(options.placeholders || {});
|
|
||||||
this.includeAnnotations = options.includeAnnotations || false;
|
this.includeAnnotations = options.includeAnnotations || false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,10 +85,16 @@ class Decoder {
|
||||||
binarystream(minor) {
|
binarystream(minor) {
|
||||||
const result = [];
|
const result = [];
|
||||||
while (!this.peekend()) {
|
while (!this.peekend()) {
|
||||||
const chunk = this.next();
|
const chunk = Annotations.stripAnnotations(this.next());
|
||||||
if (ArrayBuffer.isView(chunk)) {
|
if (ArrayBuffer.isView(chunk)) {
|
||||||
|
if (chunk.byteLength == 0) {
|
||||||
|
throw new DecodeError("Empty binary chunks are forbidden");
|
||||||
|
}
|
||||||
result.push(new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength));
|
result.push(new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength));
|
||||||
} else if (chunk instanceof Bytes) {
|
} else if (chunk instanceof Bytes) {
|
||||||
|
if (chunk._view.length == 0) {
|
||||||
|
throw new DecodeError("Empty binary chunks are forbidden");
|
||||||
|
}
|
||||||
result.push(chunk._view);
|
result.push(chunk._view);
|
||||||
} else {
|
} else {
|
||||||
const e = new DecodeError("Unexpected non-binary chunk");
|
const e = new DecodeError("Unexpected non-binary chunk");
|
||||||
|
@ -176,16 +181,7 @@ class Decoder {
|
||||||
}
|
}
|
||||||
default: throw new DecodeError("Illegal format A lead byte");
|
default: throw new DecodeError("Illegal format A lead byte");
|
||||||
}
|
}
|
||||||
case 1: {
|
case 1: throw new DecodeError("Illegal format A lead byte");
|
||||||
const n = this.wirelength(arg);
|
|
||||||
const v = this.placeholders.get(n, void 0);
|
|
||||||
if (typeof v === 'undefined') {
|
|
||||||
const e = new DecodeError("Invalid Preserves placeholder");
|
|
||||||
e.irritant = n;
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
return this.wrap(v);
|
|
||||||
}
|
|
||||||
case 2: {
|
case 2: {
|
||||||
const t = arg >> 2;
|
const t = arg >> 2;
|
||||||
const n = arg & 3;
|
const n = arg & 3;
|
||||||
|
@ -243,7 +239,6 @@ class Encoder {
|
||||||
this.chunks = [];
|
this.chunks = [];
|
||||||
this.view = new DataView(new ArrayBuffer(256));
|
this.view = new DataView(new ArrayBuffer(256));
|
||||||
this.index = 0;
|
this.index = 0;
|
||||||
this.placeholders = fromJS(options.placeholders || {});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
contents() {
|
contents() {
|
||||||
|
@ -327,11 +322,7 @@ class Encoder {
|
||||||
}
|
}
|
||||||
|
|
||||||
push(v) {
|
push(v) {
|
||||||
const placeholder = this.placeholders.get(v, void 0);
|
if (typeof v === 'object' && v !== null && typeof v[PreserveOn] === 'function') {
|
||||||
if (typeof placeholder !== 'undefined') {
|
|
||||||
this.header(0, 1, placeholder);
|
|
||||||
}
|
|
||||||
else if (typeof v === 'object' && v !== null && typeof v[PreserveOn] === 'function') {
|
|
||||||
v[PreserveOn](this);
|
v[PreserveOn](this);
|
||||||
}
|
}
|
||||||
else if (typeof v === 'boolean') {
|
else if (typeof v === 'boolean') {
|
||||||
|
|
|
@ -81,22 +81,16 @@ describe('common test suite', () => {
|
||||||
const samples_bin = fs.readFileSync(__dirname + '/../../../tests/samples.bin');
|
const samples_bin = fs.readFileSync(__dirname + '/../../../tests/samples.bin');
|
||||||
const samples = decodeWithAnnotations(samples_bin);
|
const samples = decodeWithAnnotations(samples_bin);
|
||||||
|
|
||||||
const TestCases = Record.makeConstructor('TestCases', ['mapping', 'cases']);
|
const TestCases = Record.makeConstructor('TestCases', ['cases']);
|
||||||
const ExpectedPlaceholderMapping =
|
|
||||||
Record.makeConstructor('ExpectedPlaceholderMapping', ['table']);
|
|
||||||
|
|
||||||
const expectedPlaceholderMapping = TestCases._mapping(samples.peel()).strip();
|
|
||||||
const placeholders_decode = ExpectedPlaceholderMapping._table(expectedPlaceholderMapping);
|
|
||||||
const placeholders_encode = placeholders_decode.mapEntries((e) => [e[1],e[0]]);
|
|
||||||
|
|
||||||
function DS(bs) {
|
function DS(bs) {
|
||||||
return decode(bs, {placeholders: placeholders_decode});
|
return decode(bs);
|
||||||
}
|
}
|
||||||
function D(bs) {
|
function D(bs) {
|
||||||
return decodeWithAnnotations(bs, {placeholders: placeholders_decode});
|
return decodeWithAnnotations(bs);
|
||||||
}
|
}
|
||||||
function E(v) {
|
function E(v) {
|
||||||
return encode(v, {placeholders: placeholders_encode});
|
return encode(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
const expectedValues = {
|
const expectedValues = {
|
||||||
|
@ -208,6 +202,7 @@ describe('common test suite', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
case Symbol.for('DecodeEOF'): // fall through
|
||||||
case Symbol.for('DecodeShort'):
|
case Symbol.for('DecodeShort'):
|
||||||
describe(tName, () => {
|
describe(tName, () => {
|
||||||
it('should fail with ShortPacket', () => {
|
it('should fail with ShortPacket', () => {
|
||||||
|
@ -221,6 +216,7 @@ describe('common test suite', () => {
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case Symbol.for('ParseError'):
|
case Symbol.for('ParseError'):
|
||||||
|
case Symbol.for('ParseEOF'):
|
||||||
case Symbol.for('ParseShort'):
|
case Symbol.for('ParseShort'):
|
||||||
/* Skipped for now, until we have an implementation of text syntax */
|
/* Skipped for now, until we have an implementation of text syntax */
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue