@@ -13,6 +13,7 @@ function Parser(options) {
13
13
this . _offset = 0 ;
14
14
this . _packetEnd = null ;
15
15
this . _packetHeader = null ;
16
+ this . _packetOffset = null ;
16
17
this . _onError = options . onError || function ( err ) { throw err ; } ;
17
18
this . _onPacket = options . onPacket || function ( ) { } ;
18
19
this . _nextPacketNumber = 0 ;
@@ -44,7 +45,8 @@ Parser.prototype.write = function(buffer) {
44
45
'Expected: ' + this . _nextPacketNumber
45
46
) ;
46
47
47
- err . code = 'PROTOCOL_PACKETS_OUT_OF_ORDER' ;
48
+ err . code = 'PROTOCOL_PACKETS_OUT_OF_ORDER' ;
49
+ err . fatal = true ;
48
50
49
51
this . _onError ( err ) ;
50
52
}
@@ -56,10 +58,11 @@ Parser.prototype.write = function(buffer) {
56
58
break ;
57
59
}
58
60
59
- this . _packetEnd = this . _offset + this . _packetHeader . length ;
61
+ this . _packetEnd = this . _offset + this . _packetHeader . length ;
62
+ this . _packetOffset = this . _offset ;
60
63
61
64
if ( this . _packetHeader . length === MAX_PACKET_LENGTH ) {
62
- this . _longPacketBuffers . push ( this . _buffer . slice ( this . _offset , this . _packetEnd ) ) ;
65
+ this . _longPacketBuffers . push ( this . _buffer . slice ( this . _packetOffset , this . _packetEnd ) ) ;
63
66
64
67
this . _advanceToNextPacket ( ) ;
65
68
continue ;
@@ -73,6 +76,15 @@ Parser.prototype.write = function(buffer) {
73
76
try {
74
77
this . _onPacket ( this . _packetHeader ) ;
75
78
hadException = false ;
79
+ } catch ( err ) {
80
+ if ( typeof err . code !== 'string' || err . code . substr ( 0 , 7 ) !== 'PARSER_' ) {
81
+ // Rethrow unknown errors
82
+ throw err ;
83
+ }
84
+
85
+ // Pass down parser errors
86
+ this . _onError ( err ) ;
87
+ hadException = false ;
76
88
} finally {
77
89
this . _advanceToNextPacket ( ) ;
78
90
@@ -133,7 +145,10 @@ Parser.prototype.parseUnsignedNumber = function(bytes) {
133
145
var value = 0 ;
134
146
135
147
if ( bytes > 4 ) {
136
- throw new Error ( 'parseUnsignedNumber: Supports only up to 4 bytes' ) ;
148
+ var err = new Error ( 'parseUnsignedNumber: Supports only up to 4 bytes' ) ;
149
+ err . offset = ( this . _offset - this . _packetOffset - 1 ) ;
150
+ err . code = 'PARSER_UNSIGNED_TOO_LONG' ;
151
+ throw err ;
137
152
}
138
153
139
154
while ( offset >= this . _offset ) {
@@ -168,7 +183,10 @@ Parser.prototype.parseLengthCodedBuffer = function() {
168
183
169
184
Parser . prototype . parseLengthCodedNumber = function parseLengthCodedNumber ( ) {
170
185
if ( this . _offset >= this . _buffer . length ) {
171
- throw new Error ( 'Parser: read past end' ) ;
186
+ var err = new Error ( 'Parser: read past end' ) ;
187
+ err . offset = ( this . _offset - this . _packetOffset ) ;
188
+ err . code = 'PARSER_READ_PAST_END' ;
189
+ throw err ;
172
190
}
173
191
174
192
var bits = this . _buffer [ this . _offset ++ ] ;
@@ -187,7 +205,10 @@ Parser.prototype.parseLengthCodedNumber = function parseLengthCodedNumber() {
187
205
case 254 :
188
206
break ;
189
207
default :
190
- throw new Error ( 'parseLengthCodedNumber: Unexpected first byte: 0x' + bits . toString ( 16 ) ) ;
208
+ var err = new Error ( 'Unexpected first byte' + ( bits ? ': 0x' + bits . toString ( 16 ) : '' ) ) ;
209
+ err . offset = ( this . _offset - this . _packetOffset - 1 ) ;
210
+ err . code = 'PARSER_BAD_LENGTH_BYTE' ;
211
+ throw err ;
191
212
}
192
213
193
214
var low = this . parseUnsignedNumber ( 4 ) ;
@@ -201,10 +222,13 @@ Parser.prototype.parseLengthCodedNumber = function parseLengthCodedNumber() {
201
222
return value ;
202
223
}
203
224
204
- throw new Error (
225
+ var err = new Error (
205
226
'parseLengthCodedNumber: JS precision range exceeded, ' +
206
227
'number is >= 53 bit: "' + value + '"'
207
228
) ;
229
+ err . offset = ( this . _offset - this . _packetOffset - 8 ) ;
230
+ err . code = 'PARSER_JS_PRECISION_RANGE_EXCEEDED' ;
231
+ throw err ;
208
232
}
209
233
210
234
value = low + ( MUL_32BIT * high ) ;
@@ -239,7 +263,10 @@ Parser.prototype._nullByteOffset = function() {
239
263
offset ++ ;
240
264
241
265
if ( offset >= this . _buffer . length ) {
242
- throw new Error ( 'Offset of null terminated string not found.' ) ;
266
+ var err = new Error ( 'Offset of null terminated string not found.' ) ;
267
+ err . offset = ( this . _offset - this . _packetOffset ) ;
268
+ err . code = 'PARSER_MISSING_NULL_BYTE' ;
269
+ throw err ;
243
270
}
244
271
}
245
272
@@ -374,10 +401,12 @@ Parser.prototype._combineLongPacketBuffers = function() {
374
401
this . _longPacketBuffers = [ ] ;
375
402
this . _offset = 0 ;
376
403
this . _packetEnd = this . _buffer . length - trailingPacketBytes ;
404
+ this . _packetOffset = 0 ;
377
405
} ;
378
406
379
407
Parser . prototype . _advanceToNextPacket = function ( ) {
380
408
this . _offset = this . _packetEnd ;
381
409
this . _packetHeader = null ;
382
410
this . _packetEnd = null ;
411
+ this . _packetOffset = null ;
383
412
} ;
0 commit comments