47
47
goog . provide ( 'jspb.BinaryDecoder' ) ;
48
48
49
49
goog . require ( 'jspb.asserts' ) ;
50
- goog . require ( 'goog.crypt ' ) ;
50
+ goog . require ( 'jspb.binary.utf8 ' ) ;
51
51
goog . require ( 'jspb.utils' ) ;
52
52
53
53
@@ -256,7 +256,7 @@ jspb.BinaryDecoder.prototype.setCursor = function(cursor) {
256
256
*/
257
257
jspb . BinaryDecoder . prototype . advance = function ( count ) {
258
258
this . cursor_ += count ;
259
- jspb . asserts . assert ( this . cursor_ <= this . end_ ) ;
259
+ this . checkCursor ( ) ;
260
260
} ;
261
261
262
262
@@ -397,6 +397,17 @@ jspb.BinaryDecoder.prototype.readSplitFixed64 = function(convert) {
397
397
return convert ( lowBits , highBits ) ;
398
398
} ;
399
399
400
+ /**
401
+ * Asserts that our cursor is in bounds.
402
+ *
403
+ * @private
404
+ * @return {void }
405
+ */
406
+ jspb . BinaryDecoder . prototype . checkCursor = function ( ) {
407
+ if ( this . cursor_ > this . end_ ) {
408
+ asserts . fail ( 'Read past the end ' + this . cursor_ + ' > ' + this . end_ ) ;
409
+ }
410
+ }
400
411
401
412
/**
402
413
* Skips over a varint in the block without decoding it.
@@ -452,31 +463,31 @@ jspb.BinaryDecoder.prototype.readUnsignedVarint32 = function() {
452
463
var x = ( temp & 0x7F ) ;
453
464
if ( temp < 128 ) {
454
465
this . cursor_ += 1 ;
455
- jspb . asserts . assert ( this . cursor_ <= this . end_ ) ;
466
+ this . checkCursor ( ) ;
456
467
return x ;
457
468
}
458
469
459
470
temp = bytes [ this . cursor_ + 1 ] ;
460
471
x |= ( temp & 0x7F ) << 7 ;
461
472
if ( temp < 128 ) {
462
473
this . cursor_ += 2 ;
463
- jspb . asserts . assert ( this . cursor_ <= this . end_ ) ;
474
+ this . checkCursor ( ) ;
464
475
return x ;
465
476
}
466
477
467
478
temp = bytes [ this . cursor_ + 2 ] ;
468
479
x |= ( temp & 0x7F ) << 14 ;
469
480
if ( temp < 128 ) {
470
481
this . cursor_ += 3 ;
471
- jspb . asserts . assert ( this . cursor_ <= this . end_ ) ;
482
+ this . checkCursor ( ) ;
472
483
return x ;
473
484
}
474
485
475
486
temp = bytes [ this . cursor_ + 3 ] ;
476
487
x |= ( temp & 0x7F ) << 21 ;
477
488
if ( temp < 128 ) {
478
489
this . cursor_ += 4 ;
479
- jspb . asserts . assert ( this . cursor_ <= this . end_ ) ;
490
+ this . checkCursor ( ) ;
480
491
return x ;
481
492
}
482
493
@@ -486,7 +497,7 @@ jspb.BinaryDecoder.prototype.readUnsignedVarint32 = function() {
486
497
// We're reading the high bits of an unsigned varint. The byte we just read
487
498
// also contains bits 33 through 35, which we're going to discard.
488
499
this . cursor_ += 5 ;
489
- jspb . asserts . assert ( this . cursor_ <= this . end_ ) ;
500
+ this . checkCursor ( ) ;
490
501
return x >>> 0 ;
491
502
}
492
503
@@ -500,7 +511,7 @@ jspb.BinaryDecoder.prototype.readUnsignedVarint32 = function() {
500
511
jspb . asserts . assert ( false ) ;
501
512
}
502
513
503
- jspb . asserts . assert ( this . cursor_ <= this . end_ ) ;
514
+ this . checkCursor ( ) ;
504
515
return x ;
505
516
} ;
506
517
@@ -679,7 +690,7 @@ jspb.BinaryDecoder.prototype.readZigzagVarint64String = function() {
679
690
jspb . BinaryDecoder . prototype . readUint8 = function ( ) {
680
691
var a = this . bytes_ [ this . cursor_ + 0 ] ;
681
692
this . cursor_ += 1 ;
682
- jspb . asserts . assert ( this . cursor_ <= this . end_ ) ;
693
+ this . checkCursor ( ) ;
683
694
return a ;
684
695
} ;
685
696
@@ -694,7 +705,7 @@ jspb.BinaryDecoder.prototype.readUint16 = function() {
694
705
var a = this . bytes_ [ this . cursor_ + 0 ] ;
695
706
var b = this . bytes_ [ this . cursor_ + 1 ] ;
696
707
this . cursor_ += 2 ;
697
- jspb . asserts . assert ( this . cursor_ <= this . end_ ) ;
708
+ this . checkCursor ( ) ;
698
709
return ( a << 0 ) | ( b << 8 ) ;
699
710
} ;
700
711
@@ -711,7 +722,7 @@ jspb.BinaryDecoder.prototype.readUint32 = function() {
711
722
var c = this . bytes_ [ this . cursor_ + 2 ] ;
712
723
var d = this . bytes_ [ this . cursor_ + 3 ] ;
713
724
this . cursor_ += 4 ;
714
- jspb . asserts . assert ( this . cursor_ <= this . end_ ) ;
725
+ this . checkCursor ( ) ;
715
726
return ( ( a << 0 ) | ( b << 8 ) | ( c << 16 ) | ( d << 24 ) ) >>> 0 ;
716
727
} ;
717
728
@@ -756,7 +767,7 @@ jspb.BinaryDecoder.prototype.readUint64String = function() {
756
767
jspb . BinaryDecoder . prototype . readInt8 = function ( ) {
757
768
var a = this . bytes_ [ this . cursor_ + 0 ] ;
758
769
this . cursor_ += 1 ;
759
- jspb . asserts . assert ( this . cursor_ <= this . end_ ) ;
770
+ this . checkCursor ( ) ;
760
771
return ( a << 24 ) >> 24 ;
761
772
} ;
762
773
@@ -771,7 +782,7 @@ jspb.BinaryDecoder.prototype.readInt16 = function() {
771
782
var a = this . bytes_ [ this . cursor_ + 0 ] ;
772
783
var b = this . bytes_ [ this . cursor_ + 1 ] ;
773
784
this . cursor_ += 2 ;
774
- jspb . asserts . assert ( this . cursor_ <= this . end_ ) ;
785
+ this . checkCursor ( ) ;
775
786
return ( ( ( a << 0 ) | ( b << 8 ) ) << 16 ) >> 16 ;
776
787
} ;
777
788
@@ -788,7 +799,7 @@ jspb.BinaryDecoder.prototype.readInt32 = function() {
788
799
var c = this . bytes_ [ this . cursor_ + 2 ] ;
789
800
var d = this . bytes_ [ this . cursor_ + 3 ] ;
790
801
this . cursor_ += 4 ;
791
- jspb . asserts . assert ( this . cursor_ <= this . end_ ) ;
802
+ this . checkCursor ( ) ;
792
803
return ( a << 0 ) | ( b << 8 ) | ( c << 16 ) | ( d << 24 ) ;
793
804
} ;
794
805
@@ -858,7 +869,9 @@ jspb.BinaryDecoder.prototype.readDouble = function() {
858
869
* @export
859
870
*/
860
871
jspb . BinaryDecoder . prototype . readBool = function ( ) {
861
- return ! ! this . bytes_ [ this . cursor_ ++ ] ;
872
+ const b = ! ! this . bytes_ [ this . cursor_ ++ ] ;
873
+ this . checkCursor ( ) ;
874
+ return b ;
862
875
} ;
863
876
864
877
@@ -879,59 +892,17 @@ jspb.BinaryDecoder.prototype.readEnum = function() {
879
892
* Supports codepoints from U+0000 up to U+10FFFF.
880
893
* (http://en.wikipedia.org/wiki/UTF-8).
881
894
* @param {number } length The length of the string to read.
895
+ * @param {boolean } requireUtf8 Whether to throw when invalid utf8 is found.
882
896
* @return {string } The decoded string.
883
897
* @export
884
898
*/
885
- jspb . BinaryDecoder . prototype . readString = function ( length ) {
886
- var bytes = this . bytes_ ;
887
- var cursor = this . cursor_ ;
888
- var end = cursor + length ;
889
- var codeUnits = [ ] ;
890
-
891
- var result = '' ;
892
- while ( cursor < end ) {
893
- var c = bytes [ cursor ++ ] ;
894
- if ( c < 128 ) { // Regular 7-bit ASCII.
895
- codeUnits . push ( c ) ;
896
- } else if ( c < 192 ) {
897
- // UTF-8 continuation mark. We are out of sync. This
898
- // might happen if we attempted to read a character
899
- // with more than four bytes.
900
- continue ;
901
- } else if ( c < 224 ) { // UTF-8 with two bytes.
902
- var c2 = bytes [ cursor ++ ] ;
903
- codeUnits . push ( ( ( c & 31 ) << 6 ) | ( c2 & 63 ) ) ;
904
- } else if ( c < 240 ) { // UTF-8 with three bytes.
905
- var c2 = bytes [ cursor ++ ] ;
906
- var c3 = bytes [ cursor ++ ] ;
907
- codeUnits . push ( ( ( c & 15 ) << 12 ) | ( ( c2 & 63 ) << 6 ) | ( c3 & 63 ) ) ;
908
- } else if ( c < 248 ) { // UTF-8 with 4 bytes.
909
- var c2 = bytes [ cursor ++ ] ;
910
- var c3 = bytes [ cursor ++ ] ;
911
- var c4 = bytes [ cursor ++ ] ;
912
- // Characters written on 4 bytes have 21 bits for a codepoint.
913
- // We can't fit that on 16bit characters, so we use surrogates.
914
- var codepoint =
915
- ( ( c & 7 ) << 18 ) | ( ( c2 & 63 ) << 12 ) | ( ( c3 & 63 ) << 6 ) | ( c4 & 63 ) ;
916
- // Surrogates formula from wikipedia.
917
- // 1. Subtract 0x10000 from codepoint
918
- codepoint -= 0x10000 ;
919
- // 2. Split this into the high 10-bit value and the low 10-bit value
920
- // 3. Add 0xD800 to the high value to form the high surrogate
921
- // 4. Add 0xDC00 to the low value to form the low surrogate:
922
- var low = ( codepoint & 1023 ) + 0xDC00 ;
923
- var high = ( ( codepoint >> 10 ) & 1023 ) + 0xD800 ;
924
- codeUnits . push ( high , low ) ;
925
- }
926
899
927
- // Avoid exceeding the maximum stack size when calling `apply`.
928
- if ( codeUnits . length >= 8192 ) {
929
- result += String . fromCharCode . apply ( null , codeUnits ) ;
930
- codeUnits . length = 0 ;
931
- }
932
- }
933
- result += goog . crypt . byteArrayToString ( codeUnits ) ;
934
- this . cursor_ = cursor ;
900
+ jspb . BinaryDecoder . prototype . readString = function ( length , requireUtf8 ) {
901
+ const cursor = this . cursor_ ;
902
+ this . cursor_ += length ;
903
+ this . checkCursor ( ) ;
904
+ const result =
905
+ jspb . binary . utf8 . decodeUtf8 ( jspb . asserts . assert ( this . bytes_ ) , cursor , length , requireUtf8 ) ;
935
906
return result ;
936
907
} ;
937
908
@@ -966,7 +937,7 @@ jspb.BinaryDecoder.prototype.readBytes = function(length) {
966
937
var result = this . bytes_ . subarray ( this . cursor_ , this . cursor_ + length ) ;
967
938
968
939
this . cursor_ += length ;
969
- jspb . asserts . assert ( this . cursor_ <= this . end_ ) ;
940
+ this . checkCursor ( ) ;
970
941
return result ;
971
942
} ;
972
943
0 commit comments