@@ -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