@@ -508,54 +508,37 @@ private function internal_socket_read () {
508508 return false ;
509509 }
510510
511- private function internal_uncompress_data ($ buffer, $ blen ) {
511+ private function internal_uncompress_data ($ buffer ) {
512512 // %LEN COMPRESSED UNCOMPRESSED BUFFER
513-
514- $ tlen = 0 ; // total length
515- $ clen = 0 ; // compressed length
516- $ ulen = 0 ; // uncompressed length
517- $ hlen = 0 ; // raw header length
518- $ seek1 = 0 ;
519-
520- $ start = 1 ;
521- $ counter = 0 ;
522- for ($ i = 0 ; $ i < $ blen ; $ i ++) {
523- if ($ buffer [$ i ] != ' ' ) continue ;
524- ++$ counter ;
525-
526- $ data = substr ($ buffer , $ start , $ i -$ start );
527- $ start = $ i + 1 ;
528-
529- if ($ counter == 1 ) {
530- $ tlen = intval ($ data );
531- $ seek1 = $ start ;
532- }
533- else if ($ counter == 2 ) {
534- $ clen = intval ($ data );
535- }
536- else if ($ counter == 3 ) {
537- $ ulen = intval ($ data );
538- break ;
539- }
540- }
541-
542- // sanity check header values
543- if ($ tlen == 0 || $ clen == 0 || $ ulen == 0 || $ start == 1 || $ seek1 == 0 ) return NULL ;
544-
545- // copy raw header
546- $ hlen = $ start - $ seek1 ;
547- $ header = substr ($ buffer , $ start , $ hlen );
548-
549- // compute index of the first compressed byte
550- $ start += $ hlen ;
551-
552- // perform real decompression in pure PHP code
553- $ clone = $ this ->lz4decode ($ buffer , $ start , $ header );
554-
513+
514+ // extract compressed size
515+ $ space_index = strpos ($ buffer , ' ' );
516+ $ buffer = substr ($ buffer , $ space_index + 1 );
517+
518+ // extract compressed size
519+ $ space_index = strpos ($ buffer , ' ' );
520+ $ compressed_size = intval (substr ($ buffer , 0 , $ space_index ));
521+ $ buffer = substr ($ buffer , $ space_index + 1 );
522+
523+ // extract decompressed size
524+ $ space_index = strpos ($ buffer , ' ' );
525+ $ uncompressed_size = intval (substr ($ buffer , 0 , $ space_index ));
526+ $ buffer = substr ($ buffer , $ space_index + 1 );
527+
528+ // extract data header
529+ $ header = substr ($ buffer , 0 , -$ compressed_size );
530+
531+ // extract compressed data
532+ $ compressed_buffer = substr ($ buffer , -$ compressed_size );
533+
534+ $ decompressed_buffer = $ header . $ this ->lz4decode ($ compressed_buffer , 0 );
535+
555536 // sanity check result
556- if (strlen ($ clone ) != $ ulen + $ hlen ) return NULL ;
557-
558- return $ clone ;
537+ if (strlen ($ decompressed_buffer ) != $ uncompressed_size + strlen ($ header )) {
538+ return NULL ;
539+ }
540+
541+ return $ decompressed_buffer ;
559542 }
560543
561544 private function internal_parse_value ($ buffer , &$ len , &$ cellsize = NULL , $ index = 0 ) {
@@ -601,12 +584,14 @@ private function internal_parse_buffer ($buffer, $blen) {
601584
602585 // check for compressed result
603586 if ($ buffer [0 ] == CMD_COMPRESSED ) {
604- $ buffer = $ this ->internal_uncompress_data ($ buffer, $ blen );
587+ $ buffer = $ this ->internal_uncompress_data ($ buffer );
605588 if ($ buffer == NULL ) {
606589 $ this ->errcode = -1 ;
607- $ this ->errmsg = ' An error occurred while decompressing the input buffer of len {$len}. ' ;
590+ $ this ->errmsg = " An error occurred while decompressing the input buffer of len {$ blen } . " ;
608591 return false ;
609592 }
593+ // after decompression length has changed
594+ $ blen = strlen ($ buffer );
610595 }
611596
612597 // first character contains command type
@@ -654,7 +639,10 @@ private function internal_parse_buffer ($buffer, $blen) {
654639 case CMD_ROWSET :
655640 case CMD_ROWSET_CHUNK : {
656641 // CMD_ROWSET: *LEN 0:VERSION ROWS COLS DATA
642+ // - When decompressed, LEN for ROWSET is *0
643+ //
657644 // CMD_ROWSET_CHUNK: /LEN IDX:VERSION ROWS COLS DATA
645+ //
658646 $ start = $ this ->internal_parse_rowset_signature ($ buffer , $ len , $ idx , $ version , $ nrows , $ ncols );
659647 if ($ start < 0 ) return false ;
660648
@@ -668,9 +656,11 @@ private function internal_parse_buffer ($buffer, $blen) {
668656 $ rowset = $ this ->internal_parse_rowset ($ buffer , $ start , $ idx , $ version , $ nrows , $ ncols );
669657
670658 // continue parsing next chunk in the buffer
671- $ buffer = substr ($ buffer , $ len + strlen ("/ {$ len } " ));
672- if ($ buffer ) {
673- return $ this ->internal_parse_buffer ($ buffer , strlen ($ buffer ));
659+ if ($ buffer [0 ] == CMD_ROWSET_CHUNK ) {
660+ $ buffer = substr ($ buffer , $ len + strlen ("/ {$ len } " ));
661+ if ($ buffer ) {
662+ return $ this ->internal_parse_buffer ($ buffer , strlen ($ buffer ));
663+ }
674664 }
675665
676666 return $ rowset ;
0 commit comments