forked from syndicate-lang/preserves
Fix error in format C decoding
This commit is contained in:
parent
c9484ac9ac
commit
639241c5a6
|
@ -13,6 +13,7 @@ class EncodeError extends Error {
|
||||||
this.irritant = irritant;
|
this.irritant = irritant;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
class ShortPacket extends DecodeError {}
|
||||||
|
|
||||||
class Decoder {
|
class Decoder {
|
||||||
constructor(packet, options) {
|
constructor(packet, options) {
|
||||||
|
@ -22,22 +23,18 @@ class Decoder {
|
||||||
this.shortForms = options.shortForms || {};
|
this.shortForms = options.shortForms || {};
|
||||||
}
|
}
|
||||||
|
|
||||||
peekbyte() {
|
|
||||||
if (this.index >= this.packet.length) throw new DecodeError("Short packet");
|
|
||||||
// ^ NOTE: greater-than-or-equal-to, not greater-than.
|
|
||||||
return this.packet[this.index];
|
|
||||||
}
|
|
||||||
|
|
||||||
advance(count) {
|
|
||||||
const start = this.index;
|
|
||||||
this.index += (count === void 0 ? 1 : count);
|
|
||||||
return start;
|
|
||||||
}
|
|
||||||
|
|
||||||
nextbyte() {
|
nextbyte() {
|
||||||
const val = this.peekbyte();
|
if (this.index >= this.packet.length) throw new ShortPacket("Short packet");
|
||||||
this.advance();
|
// ^ NOTE: greater-than-or-equal-to, not greater-than.
|
||||||
return val;
|
return this.packet[this.index++];
|
||||||
|
}
|
||||||
|
|
||||||
|
nextbytes(n) {
|
||||||
|
const start = this.index;
|
||||||
|
this.index += n;
|
||||||
|
if (this.index > this.packet.length) throw new ShortPacket("Short packet");
|
||||||
|
// ^ NOTE: greater-than, not greater-than-or-equal-to.
|
||||||
|
return new DataView(this.packet.buffer, this.packet.byteOffset + start, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
wirelength(arg) {
|
wirelength(arg) {
|
||||||
|
@ -52,36 +49,25 @@ class Decoder {
|
||||||
return (this.varint() << 7) + (v - 128);
|
return (this.varint() << 7) + (v - 128);
|
||||||
}
|
}
|
||||||
|
|
||||||
nextbytes(n) {
|
|
||||||
const start = this.advance(n);
|
|
||||||
if (this.index > this.packet.length) throw new DecodeError("Short packet");
|
|
||||||
// ^ NOTE: greater-than, not greater-than-or-equal-to.
|
|
||||||
return new DataView(this.packet.buffer, this.packet.byteOffset + start, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
nextvalues(n) {
|
nextvalues(n) {
|
||||||
const result = [];
|
const result = [];
|
||||||
for (let i = 0; i < n; i++) result.push(this.next());
|
for (let i = 0; i < n; i++) result.push(this.next());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
peekop() {
|
nextop() {
|
||||||
const b = this.peekbyte();
|
const b = this.nextbyte();
|
||||||
const major = b >> 6;
|
const major = b >> 6;
|
||||||
const minor = (b >> 4) & 3;
|
const minor = (b >> 4) & 3;
|
||||||
const arg = b & 15;
|
const arg = b & 15;
|
||||||
return [major, minor, arg];
|
return [major, minor, arg];
|
||||||
}
|
}
|
||||||
|
|
||||||
nextop() {
|
|
||||||
const op = this.peekop();
|
|
||||||
this.advance();
|
|
||||||
return op;
|
|
||||||
}
|
|
||||||
|
|
||||||
peekend(arg) {
|
peekend(arg) {
|
||||||
const [a,i,r] = this.peekop();
|
const [a,i,r] = this.nextop();
|
||||||
return (a === 0) && (i === 3) && (r === arg);
|
const result = (a === 0) && (i === 3) && (r === arg);
|
||||||
|
if (!result) this.index--;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
binarystream(arg, minor) {
|
binarystream(arg, minor) {
|
||||||
|
@ -335,6 +321,7 @@ class Encoder {
|
||||||
Object.assign(module.exports, {
|
Object.assign(module.exports, {
|
||||||
DecodeError,
|
DecodeError,
|
||||||
EncodeError,
|
EncodeError,
|
||||||
|
ShortPacket,
|
||||||
Decoder,
|
Decoder,
|
||||||
Encoder,
|
Encoder,
|
||||||
});
|
});
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
26626865626c6c6060616f36
|
26626865626c6c6060616f36
|
||||||
27626865626c6c6060616f37
|
27626865626c6c6060616f37
|
||||||
2c111213143c
|
2c111213143c
|
||||||
|
2c2563616263352563646566353c
|
||||||
2cc2516111c2516212c25163133c
|
2cc2516111c2516212c25163133c
|
||||||
410d
|
410d
|
||||||
417f
|
417f
|
||||||
|
|
|
@ -71,6 +71,7 @@ describe('hex samples', () => {
|
||||||
{ expected: Bytes.from("hello"), encodesTo: '6568656c6c6f', },
|
{ expected: Bytes.from("hello"), encodesTo: '6568656c6c6f', },
|
||||||
{ expected: Symbol.for("hello"), encodesTo: '7568656c6c6f', },
|
{ expected: Symbol.for("hello"), encodesTo: '7568656c6c6f', },
|
||||||
{ expected: Immutable.Seq([1, 2, 3, 4]), },
|
{ expected: Immutable.Seq([1, 2, 3, 4]), },
|
||||||
|
{ expected: Preserves.fromJS(["abc", "def"]), encodesTo: 'c25361626353646566' },
|
||||||
{ expected: Preserves.fromJS([["a", 1], ["b", 2], ["c", 3]]),
|
{ expected: Preserves.fromJS([["a", 1], ["b", 2], ["c", 3]]),
|
||||||
encodesTo: 'c3c2516111c2516212c2516313', },
|
encodesTo: 'c3c2516111c2516212c2516313', },
|
||||||
{ expected: 13, },
|
{ expected: 13, },
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from .preserves import Float, Symbol, Record, ImmutableDict
|
from .preserves import Float, Symbol, Record, ImmutableDict
|
||||||
|
|
||||||
from .preserves import DecodeError, EncodeError
|
from .preserves import DecodeError, EncodeError, ShortPacket
|
||||||
|
|
||||||
from .preserves import Decoder, Encoder
|
from .preserves import Decoder, Encoder
|
||||||
|
|
||||||
|
|
|
@ -119,6 +119,7 @@ def dict_kvs(d):
|
||||||
|
|
||||||
class DecodeError(ValueError): pass
|
class DecodeError(ValueError): pass
|
||||||
class EncodeError(ValueError): pass
|
class EncodeError(ValueError): pass
|
||||||
|
class ShortPacket(DecodeError): pass
|
||||||
|
|
||||||
class Codec(object):
|
class Codec(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -183,21 +184,19 @@ class Decoder(Codec):
|
||||||
self.packet = packet
|
self.packet = packet
|
||||||
self.index = 0
|
self.index = 0
|
||||||
|
|
||||||
def peekbyte(self):
|
|
||||||
if self.index < len(self.packet):
|
|
||||||
return _ord(self.packet[self.index])
|
|
||||||
else:
|
|
||||||
raise DecodeError('Short packet')
|
|
||||||
|
|
||||||
def advance(self, count=1):
|
|
||||||
start = self.index
|
|
||||||
self.index = self.index + count
|
|
||||||
return start
|
|
||||||
|
|
||||||
def nextbyte(self):
|
def nextbyte(self):
|
||||||
val = self.peekbyte()
|
if self.index >= len(self.packet):
|
||||||
self.advance()
|
raise ShortPacket('Short packet')
|
||||||
return val
|
self.index = self.index + 1
|
||||||
|
return _ord(self.packet[self.index - 1])
|
||||||
|
|
||||||
|
def nextbytes(self, n):
|
||||||
|
start = self.index
|
||||||
|
end = start + n
|
||||||
|
if end > len(self.packet):
|
||||||
|
raise ShortPacket('Short packet')
|
||||||
|
self.index = end
|
||||||
|
return self.packet[start : end]
|
||||||
|
|
||||||
def wirelength(self, arg):
|
def wirelength(self, arg):
|
||||||
if arg < 15:
|
if arg < 15:
|
||||||
|
@ -211,30 +210,24 @@ class Decoder(Codec):
|
||||||
else:
|
else:
|
||||||
return self.varint() * 128 + (v - 128)
|
return self.varint() * 128 + (v - 128)
|
||||||
|
|
||||||
def nextbytes(self, n):
|
|
||||||
start = self.advance(n)
|
|
||||||
return self.packet[start : self.index]
|
|
||||||
|
|
||||||
def nextvalues(self, n):
|
def nextvalues(self, n):
|
||||||
result = []
|
result = []
|
||||||
for i in range(n):
|
for i in range(n):
|
||||||
result.append(self.next())
|
result.append(self.next())
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def peekop(self):
|
def nextop(self):
|
||||||
b = self.peekbyte()
|
b = self.nextbyte()
|
||||||
major = b >> 6
|
major = b >> 6
|
||||||
minor = (b >> 4) & 3
|
minor = (b >> 4) & 3
|
||||||
arg = b & 15
|
arg = b & 15
|
||||||
return (major, minor, arg)
|
return (major, minor, arg)
|
||||||
|
|
||||||
def nextop(self):
|
|
||||||
op = self.peekop()
|
|
||||||
self.advance()
|
|
||||||
return op
|
|
||||||
|
|
||||||
def peekend(self, arg):
|
def peekend(self, arg):
|
||||||
return self.peekop() == (0, 3, arg)
|
matched = (self.nextop() == (0, 3, arg))
|
||||||
|
if not matched:
|
||||||
|
self.index = self.index - 1
|
||||||
|
return matched
|
||||||
|
|
||||||
def binarystream(self, arg, minor):
|
def binarystream(self, arg, minor):
|
||||||
result = []
|
result = []
|
||||||
|
|
|
@ -199,3 +199,8 @@ class CodecTests(unittest.TestCase):
|
||||||
self._roundtrip((False,) * 15, _buf(0xCF, 0x0F, b'\x00' * 15))
|
self._roundtrip((False,) * 15, _buf(0xCF, 0x0F, b'\x00' * 15))
|
||||||
self._roundtrip((False,) * 100, _buf(0xCF, 0x64, b'\x00' * 100))
|
self._roundtrip((False,) * 100, _buf(0xCF, 0x64, b'\x00' * 100))
|
||||||
self._roundtrip((False,) * 200, _buf(0xCF, 0xC8, 0x01, b'\x00' * 200))
|
self._roundtrip((False,) * 200, _buf(0xCF, 0xC8, 0x01, b'\x00' * 200))
|
||||||
|
|
||||||
|
def test_format_c_twice(self):
|
||||||
|
self._roundtrip(SequenceStream([StringStream([b'abc']), StringStream([b'def'])]),
|
||||||
|
_buf(0x2C, 0x25, 0x63, 'abc', 0x35, 0x25, 0x63, 'def', 0x35, 0x3C),
|
||||||
|
back=(u'abc', u'def'))
|
||||||
|
|
Loading…
Reference in New Issue