4747goog . provide ( 'jspb.BinaryDecoder' ) ;
4848
4949goog . require ( 'jspb.asserts' ) ;
50- goog . require ( 'goog.crypt ' ) ;
50+ goog . require ( 'jspb.binary.utf8 ' ) ;
5151goog . require ( 'jspb.utils' ) ;
5252
5353
@@ -256,7 +256,7 @@ jspb.BinaryDecoder.prototype.setCursor = function(cursor) {
256256 */
257257jspb . BinaryDecoder . prototype . advance = function ( count ) {
258258 this . cursor_ += count ;
259- jspb . asserts . assert ( this . cursor_ <= this . end_ ) ;
259+ this . checkCursor ( ) ;
260260} ;
261261
262262
@@ -397,6 +397,17 @@ jspb.BinaryDecoder.prototype.readSplitFixed64 = function(convert) {
397397 return convert ( lowBits , highBits ) ;
398398} ;
399399
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+ }
400411
401412/**
402413 * Skips over a varint in the block without decoding it.
@@ -452,31 +463,31 @@ jspb.BinaryDecoder.prototype.readUnsignedVarint32 = function() {
452463 var x = ( temp & 0x7F ) ;
453464 if ( temp < 128 ) {
454465 this . cursor_ += 1 ;
455- jspb . asserts . assert ( this . cursor_ <= this . end_ ) ;
466+ this . checkCursor ( ) ;
456467 return x ;
457468 }
458469
459470 temp = bytes [ this . cursor_ + 1 ] ;
460471 x |= ( temp & 0x7F ) << 7 ;
461472 if ( temp < 128 ) {
462473 this . cursor_ += 2 ;
463- jspb . asserts . assert ( this . cursor_ <= this . end_ ) ;
474+ this . checkCursor ( ) ;
464475 return x ;
465476 }
466477
467478 temp = bytes [ this . cursor_ + 2 ] ;
468479 x |= ( temp & 0x7F ) << 14 ;
469480 if ( temp < 128 ) {
470481 this . cursor_ += 3 ;
471- jspb . asserts . assert ( this . cursor_ <= this . end_ ) ;
482+ this . checkCursor ( ) ;
472483 return x ;
473484 }
474485
475486 temp = bytes [ this . cursor_ + 3 ] ;
476487 x |= ( temp & 0x7F ) << 21 ;
477488 if ( temp < 128 ) {
478489 this . cursor_ += 4 ;
479- jspb . asserts . assert ( this . cursor_ <= this . end_ ) ;
490+ this . checkCursor ( ) ;
480491 return x ;
481492 }
482493
@@ -486,7 +497,7 @@ jspb.BinaryDecoder.prototype.readUnsignedVarint32 = function() {
486497 // We're reading the high bits of an unsigned varint. The byte we just read
487498 // also contains bits 33 through 35, which we're going to discard.
488499 this . cursor_ += 5 ;
489- jspb . asserts . assert ( this . cursor_ <= this . end_ ) ;
500+ this . checkCursor ( ) ;
490501 return x >>> 0 ;
491502 }
492503
@@ -500,7 +511,7 @@ jspb.BinaryDecoder.prototype.readUnsignedVarint32 = function() {
500511 jspb . asserts . assert ( false ) ;
501512 }
502513
503- jspb . asserts . assert ( this . cursor_ <= this . end_ ) ;
514+ this . checkCursor ( ) ;
504515 return x ;
505516} ;
506517
@@ -679,7 +690,7 @@ jspb.BinaryDecoder.prototype.readZigzagVarint64String = function() {
679690jspb . BinaryDecoder . prototype . readUint8 = function ( ) {
680691 var a = this . bytes_ [ this . cursor_ + 0 ] ;
681692 this . cursor_ += 1 ;
682- jspb . asserts . assert ( this . cursor_ <= this . end_ ) ;
693+ this . checkCursor ( ) ;
683694 return a ;
684695} ;
685696
@@ -694,7 +705,7 @@ jspb.BinaryDecoder.prototype.readUint16 = function() {
694705 var a = this . bytes_ [ this . cursor_ + 0 ] ;
695706 var b = this . bytes_ [ this . cursor_ + 1 ] ;
696707 this . cursor_ += 2 ;
697- jspb . asserts . assert ( this . cursor_ <= this . end_ ) ;
708+ this . checkCursor ( ) ;
698709 return ( a << 0 ) | ( b << 8 ) ;
699710} ;
700711
@@ -711,7 +722,7 @@ jspb.BinaryDecoder.prototype.readUint32 = function() {
711722 var c = this . bytes_ [ this . cursor_ + 2 ] ;
712723 var d = this . bytes_ [ this . cursor_ + 3 ] ;
713724 this . cursor_ += 4 ;
714- jspb . asserts . assert ( this . cursor_ <= this . end_ ) ;
725+ this . checkCursor ( ) ;
715726 return ( ( a << 0 ) | ( b << 8 ) | ( c << 16 ) | ( d << 24 ) ) >>> 0 ;
716727} ;
717728
@@ -756,7 +767,7 @@ jspb.BinaryDecoder.prototype.readUint64String = function() {
756767jspb . BinaryDecoder . prototype . readInt8 = function ( ) {
757768 var a = this . bytes_ [ this . cursor_ + 0 ] ;
758769 this . cursor_ += 1 ;
759- jspb . asserts . assert ( this . cursor_ <= this . end_ ) ;
770+ this . checkCursor ( ) ;
760771 return ( a << 24 ) >> 24 ;
761772} ;
762773
@@ -771,7 +782,7 @@ jspb.BinaryDecoder.prototype.readInt16 = function() {
771782 var a = this . bytes_ [ this . cursor_ + 0 ] ;
772783 var b = this . bytes_ [ this . cursor_ + 1 ] ;
773784 this . cursor_ += 2 ;
774- jspb . asserts . assert ( this . cursor_ <= this . end_ ) ;
785+ this . checkCursor ( ) ;
775786 return ( ( ( a << 0 ) | ( b << 8 ) ) << 16 ) >> 16 ;
776787} ;
777788
@@ -788,7 +799,7 @@ jspb.BinaryDecoder.prototype.readInt32 = function() {
788799 var c = this . bytes_ [ this . cursor_ + 2 ] ;
789800 var d = this . bytes_ [ this . cursor_ + 3 ] ;
790801 this . cursor_ += 4 ;
791- jspb . asserts . assert ( this . cursor_ <= this . end_ ) ;
802+ this . checkCursor ( ) ;
792803 return ( a << 0 ) | ( b << 8 ) | ( c << 16 ) | ( d << 24 ) ;
793804} ;
794805
@@ -858,7 +869,9 @@ jspb.BinaryDecoder.prototype.readDouble = function() {
858869 * @export
859870 */
860871jspb . BinaryDecoder . prototype . readBool = function ( ) {
861- return ! ! this . bytes_ [ this . cursor_ ++ ] ;
872+ const b = ! ! this . bytes_ [ this . cursor_ ++ ] ;
873+ this . checkCursor ( ) ;
874+ return b ;
862875} ;
863876
864877
@@ -879,59 +892,17 @@ jspb.BinaryDecoder.prototype.readEnum = function() {
879892 * Supports codepoints from U+0000 up to U+10FFFF.
880893 * (http://en.wikipedia.org/wiki/UTF-8).
881894 * @param {number } length The length of the string to read.
895+ * @param {boolean } requireUtf8 Whether to throw when invalid utf8 is found.
882896 * @return {string } The decoded string.
883897 * @export
884898 */
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- }
926899
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 ) ;
935906 return result ;
936907} ;
937908
@@ -966,7 +937,7 @@ jspb.BinaryDecoder.prototype.readBytes = function(length) {
966937 var result = this . bytes_ . subarray ( this . cursor_ , this . cursor_ + length ) ;
967938
968939 this . cursor_ += length ;
969- jspb . asserts . assert ( this . cursor_ <= this . end_ ) ;
940+ this . checkCursor ( ) ;
970941 return result ;
971942} ;
972943
0 commit comments