@@ -2748,19 +2748,7 @@ static uint8_t crc8(unsigned char *input, size_t len) {
27482748#endif 
27492749
27502750PHP_REDIS_API  int 
2751- redis_pack (RedisSock  * redis_sock , zval  * z , char  * * val , size_t  * val_len )
2752- {
2753-     char  * buf ;
2754-     int  valfree ;
2755-     size_t  len ;
2756- 
2757-     valfree  =  redis_serialize (redis_sock , z , & buf , & len );
2758-     if  (redis_sock -> compression  ==  REDIS_COMPRESSION_NONE ) {
2759-         * val  =  buf ;
2760-         * val_len  =  len ;
2761-         return  valfree ;
2762-     }
2763- 
2751+ redis_compress (RedisSock  * redis_sock , char  * * dst , size_t  * dstlen , char  * buf , size_t  len ) {
27642752    switch  (redis_sock -> compression ) {
27652753        case  REDIS_COMPRESSION_LZF :
27662754#ifdef  HAVE_REDIS_LZF 
@@ -2773,9 +2761,8 @@ redis_pack(RedisSock *redis_sock, zval *z, char **val, size_t *val_len)
27732761                size  =  len  +  MIN (UINT_MAX  -  len , MAX (LZF_MARGIN , len  / 25 ));
27742762                data  =  emalloc (size );
27752763                if  ((res  =  lzf_compress (buf , len , data , size )) >  0 ) {
2776-                     if  (valfree ) efree (buf );
2777-                     * val  =  data ;
2778-                     * val_len  =  res ;
2764+                     * dst  =  data ;
2765+                     * dstlen  =  res ;
27792766                    return  1 ;
27802767                }
27812768                efree (data );
@@ -2805,10 +2792,8 @@ redis_pack(RedisSock *redis_sock, zval *z, char **val, size_t *val_len)
28052792                data  =  emalloc (size );
28062793                size  =  ZSTD_compress (data , size , buf , len , level );
28072794                if  (!ZSTD_isError (size )) {
2808-                     if  (valfree ) efree (buf );
2809-                     data  =  erealloc (data , size );
2810-                     * val  =  data ;
2811-                     * val_len  =  size ;
2795+                     * dst  =  erealloc (data , size );
2796+                     * dstlen  =  size ;
28122797                    return  1 ;
28132798                }
28142799                efree (data );
@@ -2856,22 +2841,21 @@ redis_pack(RedisSock *redis_sock, zval *z, char **val, size_t *val_len)
28562841                    break ;
28572842                }
28582843
2859-                 if  (valfree ) efree (buf );
2860-                 * val  =  lz4buf ;
2861-                 * val_len  =  lz4len  +  REDIS_LZ4_HDR_SIZE ;
2844+                 * dst  =  lz4buf ;
2845+                 * dstlen  =  lz4len  +  REDIS_LZ4_HDR_SIZE ;
28622846                return  1 ;
28632847            }
28642848#endif 
28652849            break ;
28662850    }
2867-     * val  =  buf ;
2868-     * val_len  =  len ;
2869-     return  valfree ;
2851+ 
2852+     * dst  =  buf ;
2853+     * dstlen  =  len ;
2854+     return  0 ;
28702855}
28712856
28722857PHP_REDIS_API  int 
2873- redis_unpack (RedisSock  * redis_sock , const  char  * val , int  val_len , zval  * z_ret )
2874- {
2858+ redis_uncompress (RedisSock  * redis_sock , char  * * dst , size_t  * dstlen , const  char  * src , size_t  len ) {
28752859    switch  (redis_sock -> compression ) {
28762860        case  REDIS_COMPRESSION_LZF :
28772861#ifdef  HAVE_REDIS_LZF 
@@ -2880,50 +2864,49 @@ redis_unpack(RedisSock *redis_sock, const char *val, int val_len, zval *z_ret)
28802864                int  i ;
28812865                uint32_t  res ;
28822866
2883-                 if  (val_len  ==  0 )
2867+                 if  (len  ==  0 )
28842868                    break ;
28852869
28862870                /* start from two-times bigger buffer and 
28872871                 * increase it exponentially  if needed */ 
28882872                errno  =  E2BIG ;
28892873                for  (i  =  2 ; errno  ==  E2BIG ; i  *= 2 ) {
2890-                     data  =  emalloc (i  *  val_len );
2891-                     if  ((res  =  lzf_decompress (val ,  val_len , data , i  *  val_len )) ==  0 ) {
2874+                     data  =  emalloc (i  *  len );
2875+                     if  ((res  =  lzf_decompress (src ,  len , data , i  *  len )) ==  0 ) {
28922876                        /* errno != E2BIG will brake for loop */ 
28932877                        efree (data );
28942878                        continue ;
2895-                     } else  if  (redis_unserialize (redis_sock , data , res , z_ret ) ==  0 ) {
2896-                         ZVAL_STRINGL (z_ret , data , res );
28972879                    }
2898-                     efree (data );
2880+ 
2881+                     * dst  =  data ;
2882+                     * dstlen  =  res ;
28992883                    return  1 ;
29002884                }
2885+ 
2886+                 efree (data );
2887+                 break ;
29012888            }
29022889#endif 
29032890            break ;
29042891        case  REDIS_COMPRESSION_ZSTD :
29052892#ifdef  HAVE_REDIS_ZSTD 
29062893            {
29072894                char  * data ;
2908-                 unsigned long long  len ;
2895+                 unsigned long long  zlen ;
29092896
2910-                 len  =  ZSTD_getFrameContentSize (val , val_len );
2911- 
2912-                 if  (len  !=  ZSTD_CONTENTSIZE_ERROR  &&  len  !=  ZSTD_CONTENTSIZE_UNKNOWN  &&  len  <= INT_MAX )
2913-                 {
2914-                     size_t  zlen ;
2897+                 zlen  =  ZSTD_getFrameContentSize (src , len );
2898+                 if  (zlen  ==  ZSTD_CONTENTSIZE_ERROR  ||  zlen  ==  ZSTD_CONTENTSIZE_UNKNOWN  ||  zlen  >  INT_MAX )
2899+                     break ;
29152900
2916-                     data  =  emalloc (len );
2917-                     zlen  =  ZSTD_decompress (data , len , val , val_len );
2918-                     if  (ZSTD_isError (zlen ) ||  zlen  !=  len ) {
2919-                         efree (data );
2920-                         break ;
2921-                     } else  if  (redis_unserialize (redis_sock , data , zlen , z_ret ) ==  0 ) {
2922-                         ZVAL_STRINGL (z_ret , data , zlen );
2923-                     }
2901+                 data  =  emalloc (zlen );
2902+                 * dstlen  =  ZSTD_decompress (data , zlen , src , len );
2903+                 if  (ZSTD_isError (* dstlen ) ||  * dstlen  !=  zlen ) {
29242904                    efree (data );
2925-                     return   1 ;
2905+                     break ;
29262906                }
2907+ 
2908+                 * dst  =  data ;
2909+                 return  1 ;
29272910            }
29282911#endif 
29292912            break ;
@@ -2936,12 +2919,12 @@ redis_unpack(RedisSock *redis_sock, const char *val, int val_len, zval *z_ret)
29362919
29372920                /* We must have at least enough bytes for our header, and can't have more than 
29382921                 * INT_MAX + our header size. */ 
2939-                 if  (val_len  <  REDIS_LZ4_HDR_SIZE  ||  val_len  >  INT_MAX  +  REDIS_LZ4_HDR_SIZE )
2922+                 if  (len  <  REDIS_LZ4_HDR_SIZE  ||  len  >  INT_MAX  +  REDIS_LZ4_HDR_SIZE )
29402923                    break ;
29412924
29422925                /* Operate on copies in case our CRC fails */ 
2943-                 const  char  * copy  =  val ;
2944-                 size_t  copylen  =  val_len ;
2926+                 const  char  * copy  =  src ;
2927+                 size_t  copylen  =  len ;
29452928
29462929                /* Read in our header bytes */ 
29472930                memcpy (& lz4crc , copy , sizeof (uint8_t ));
@@ -2956,23 +2939,59 @@ redis_unpack(RedisSock *redis_sock, const char *val, int val_len, zval *z_ret)
29562939                /* Finally attempt decompression */ 
29572940                data  =  emalloc (datalen );
29582941                if  (LZ4_decompress_safe (copy , data , copylen , datalen ) >  0 ) {
2959-                     if  (redis_unserialize (redis_sock , data , datalen , z_ret ) ==  0 ) {
2960-                         ZVAL_STRINGL (z_ret , data , datalen );
2961-                     }
2962-                     efree (data );
2942+                     * dst  =  data ;
2943+                     * dstlen  =  datalen ;
29632944                    return  1 ;
29642945                }
2946+ 
29652947                efree (data );
29662948            }
29672949#endif 
29682950            break ;
29692951    }
2970-     return  redis_unserialize (redis_sock , val , val_len , z_ret );
2952+ 
2953+     * dst  =  (char * )src ;
2954+     * dstlen  =  len ;
2955+     return  0 ;
2956+ }
2957+ 
2958+ PHP_REDIS_API  int 
2959+ redis_pack (RedisSock  * redis_sock , zval  * z , char  * * val , size_t  * val_len ) {
2960+     size_t  tmplen ;
2961+     int  tmpfree ;
2962+     char  * tmp ;
2963+ 
2964+     /* First serialize */ 
2965+     tmpfree  =  redis_serialize (redis_sock , z , & tmp , & tmplen );
2966+ 
2967+     /* Now attempt compression */ 
2968+     if  (redis_compress (redis_sock , val , val_len , tmp , tmplen )) {
2969+         if  (tmpfree ) efree (tmp );
2970+         return  1 ;
2971+     }
2972+ 
2973+     return  tmpfree ;
2974+ }
2975+ 
2976+ PHP_REDIS_API  int 
2977+ redis_unpack (RedisSock  * redis_sock , const  char  * src , int  srclen , zval  * zdst ) {
2978+     size_t  len ;
2979+     char  * buf ;
2980+ 
2981+     /* Uncompress, then unserialize */ 
2982+     if  (redis_uncompress (redis_sock , & buf , & len , src , srclen )) {
2983+         if  (!redis_unserialize (redis_sock , buf , len , zdst )) {
2984+             ZVAL_STRINGL (zdst , buf , len );
2985+         }
2986+         efree (buf );
2987+         return  1 ;
2988+     }
2989+ 
2990+     return  redis_unserialize (redis_sock , buf , len , zdst );
29712991}
29722992
29732993PHP_REDIS_API  int 
2974- redis_serialize (RedisSock  * redis_sock , zval  * z , char  * * val , size_t  * val_len 
2975-                )
2994+ redis_serialize (RedisSock  * redis_sock , zval  * z , char  * * val , size_t  * val_len )
29762995{
29772996    php_serialize_data_t  ht ;
29782997
0 commit comments