Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

Keisial

By: a guest on Sep 19th, 2008  |  syntax: C  |  size: 7.27 KB  |  views: 264  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. --- php5.2-200809191430\ext\bz2\bz2_filter.c    2008-01-13 00:35:00.000000000 +0100
  2. +++ php5.2-200809181030\ext\bz2\bz2_filter.c    2008-09-19 18:41:52.000000000 +0200
  3.  -27,6 +27,13 @@
  4.  
  5.  /* {{{ data structure */
  6.  
  7. +enum strm_status {
  8. +    Uninitialised,
  9. +    Running,
  10. +    Finished
  11. +};
  12. +    
  13. +
  14.  typedef struct _php_bz2_filter_data {
  15.         int persistent;
  16.         bz_stream strm;
  17.  -34,6 +41,11 @@
  18.         size_t inbuf_len;
  19.         char *outbuf;
  20.         size_t outbuf_len;
  21. +      
  22. +       /* Decompress options */
  23. +       enum strm_status status;
  24. +       unsigned int small_footprint : 1;
  25. +    int expect_concatenated : 1;          
  26.  } php_bz2_filter_data;
  27.  
  28.  /* }}} */
  29.  -65,7 +77,7 @@
  30.         php_bz2_filter_data *data;
  31.         php_stream_bucket *bucket;
  32.         size_t consumed = 0;
  33. -       int status;
  34. +       int bzlib_status;
  35.         php_stream_filter_status_t exit_status = PSFS_FEED_ME;
  36.         bz_stream *streamp;
  37.  
  38.  -82,47 +94,72 @@
  39.  
  40.                 bucket = php_stream_bucket_make_writeable(buckets_in->head TSRMLS_CC);
  41.                 while (bin < bucket->buflen) {
  42. -                       desired = bucket->buflen - bin;
  43. -                       if (desired > data->inbuf_len) {
  44. -                               desired = data->inbuf_len;
  45. -                       }
  46. -                       memcpy(data->strm.next_in, bucket->buf + bin, desired);
  47. -                       data->strm.avail_in = desired;
  48. +            if (data->status == Uninitialised) {                
  49. +                bzlib_status = BZ2_bzDecompressInit(streamp, 0, data->small_footprint);
  50.  
  51. -                       status = BZ2_bzDecompress(&(data->strm));
  52. -                       if (status != BZ_OK && status != BZ_STREAM_END) {
  53. -                               /* Something bad happened */
  54. -                               php_stream_bucket_delref(bucket TSRMLS_CC);
  55. -                               return PSFS_ERR_FATAL;
  56. -                       }
  57. -                       desired -= data->strm.avail_in; /* desired becomes what we consumed this round through */
  58. -                       data->strm.next_in = data->inbuf;
  59. -                       data->strm.avail_in = 0;
  60. -                       consumed += desired;
  61. -                       bin += desired;
  62. +                if (BZ_OK != bzlib_status)
  63. +                    return PSFS_ERR_FATAL;
  64.  
  65. -                       if (data->strm.avail_out < data->outbuf_len) {
  66. -                               php_stream_bucket *out_bucket;
  67. -                               size_t bucketlen = data->outbuf_len - data->strm.avail_out;
  68. -                               out_bucket = php_stream_bucket_new(stream, estrndup(data->outbuf, bucketlen), bucketlen, 1, 0 TSRMLS_CC);
  69. -                               php_stream_bucket_append(buckets_out, out_bucket TSRMLS_CC);
  70. -                               data->strm.avail_out = data->outbuf_len;
  71. -                               data->strm.next_out = data->outbuf;
  72. -                               exit_status = PSFS_PASS_ON;
  73. -                       } else if (status == BZ_STREAM_END && data->strm.avail_out >= data->outbuf_len) {
  74. -                               /* no more data to decompress, and nothing was spat out */
  75. -                               php_stream_bucket_delref(bucket TSRMLS_CC);
  76. -                               return PSFS_PASS_ON;
  77. -                       }
  78. +                data->status = Running;
  79. +            }
  80. +                    
  81. +            if (data->status == Running) {
  82. +                       desired = bucket->buflen - bin;
  83. +                       if (desired > data->inbuf_len) {
  84. +                               desired = data->inbuf_len;
  85. +                       }
  86. +                       memcpy(data->strm.next_in, bucket->buf + bin, desired);
  87. +                       data->strm.avail_in = desired;
  88. +    
  89. +                       bzlib_status = BZ2_bzDecompress(&(data->strm));
  90. +                      
  91. +                       if (bzlib_status == BZ_STREAM_END) {
  92. +                    BZ2_bzDecompressEnd(&(data->strm));
  93. +                    if (data->expect_concatenated)
  94. +                        data->status = Uninitialised;
  95. +                    else
  96. +                        data->status = Finished;
  97. +                } else
  98. +                       if (bzlib_status != BZ_OK) {
  99. +                               /* Something bad happened */
  100. +                               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bzip decompress error %d.", bzlib_status);
  101. +    
  102. +                               php_stream_bucket_delref(bucket TSRMLS_CC);
  103. +                               return PSFS_ERR_FATAL;
  104. +                       }
  105. +                       desired -= data->strm.avail_in; /* desired becomes what we consumed this round through */
  106. +                       data->strm.next_in = data->inbuf;
  107. +                       data->strm.avail_in = 0;
  108. +                       consumed += desired;
  109. +                       bin += desired;
  110. +    
  111. +                       if (data->strm.avail_out < data->outbuf_len) {
  112. +                               php_stream_bucket *out_bucket;
  113. +                               size_t bucketlen = data->outbuf_len - data->strm.avail_out;
  114. +                               out_bucket = php_stream_bucket_new(stream, estrndup(data->outbuf, bucketlen), bucketlen, 1, 0 TSRMLS_CC);
  115. +                               php_stream_bucket_append(buckets_out, out_bucket TSRMLS_CC);
  116. +                               data->strm.avail_out = data->outbuf_len;
  117. +                               data->strm.next_out = data->outbuf;
  118. +                               exit_status = PSFS_PASS_ON;
  119. +                       } else if (bzlib_status == BZ_STREAM_END && data->strm.avail_out >= data->outbuf_len) {
  120. +                               /* no more data to decompress, and nothing was spat out */
  121. +                               php_stream_bucket_delref(bucket TSRMLS_CC);
  122. +                               return PSFS_PASS_ON;
  123. +                       }
  124. +               } else {
  125. +                consumed += bucket->buflen;
  126. +                break;
  127. +            }
  128.                 }
  129. +
  130.                 php_stream_bucket_delref(bucket TSRMLS_CC);
  131.         }
  132.  
  133. -       if (flags & PSFS_FLAG_FLUSH_CLOSE) {
  134. +       if ((data->status == Running) && (flags & PSFS_FLAG_FLUSH_CLOSE)) {
  135.                 /* Spit it out! */
  136. -               status = BZ_OK;
  137. -               while (status == BZ_OK) {
  138. -                       status = BZ2_bzDecompress(&(data->strm));
  139. +               bzlib_status = BZ_OK;
  140. +               while (bzlib_status == BZ_OK) {
  141. +                       bzlib_status = BZ2_bzDecompress(&(data->strm));
  142.                         if (data->strm.avail_out < data->outbuf_len) {
  143.                                 size_t bucketlen = data->outbuf_len - data->strm.avail_out;
  144.  
  145.  -131,7 +168,7 @@
  146.                                 data->strm.avail_out = data->outbuf_len;
  147.                                 data->strm.next_out = data->outbuf;
  148.                                 exit_status = PSFS_PASS_ON;
  149. -                       } else if (status == BZ_OK) {
  150. +                       } else if (bzlib_status == BZ_OK) {
  151.                                 break;
  152.                         }
  153.                 }
  154.  -148,7 +185,7 @@
  155.  {
  156.         if (thisfilter && thisfilter->abstract) {
  157.                 php_bz2_filter_data *data = thisfilter->abstract;
  158. -               BZ2_bzDecompressEnd(&(data->strm));
  159. +               if (data->status == Running) BZ2_bzDecompressEnd(&(data->strm));
  160.                 pefree(data->inbuf, data->persistent);
  161.                 pefree(data->outbuf, data->persistent);
  162.                 pefree(data, data->persistent);
  163.  -275,7 +312,7 @@
  164.  {
  165.         php_stream_filter_ops *fops = NULL;
  166.         php_bz2_filter_data *data;
  167. -       int status;
  168. +       int status = BZ_OK;
  169.  
  170.         /* Create this filter */
  171.         data = pecalloc(1, sizeof(php_bz2_filter_data), persistent);
  172.  -307,12 +344,22 @@
  173.         }
  174.  
  175.         if (strcasecmp(filtername, "bzip2.decompress") == 0) {
  176. -               int smallFootprint = 0;
  177. -
  178. +               data->small_footprint = 0;
  179. +               data->expect_concatenated = 0;
  180. +    
  181.                 if (filterparams) {
  182.                         zval **tmpzval = NULL;
  183.  
  184.                         if (Z_TYPE_P(filterparams) == IS_ARRAY || Z_TYPE_P(filterparams) == IS_OBJECT) {
  185. +                
  186. +                if (SUCCESS == zend_hash_find(HASH_OF(filterparams), "concatenated", sizeof("concatenated"), (void **) &tmpzval) ) {
  187. +                               SEPARATE_ZVAL(tmpzval);
  188. +                               convert_to_boolean_ex(tmpzval);
  189. +                               data->expect_concatenated = Z_LVAL_PP(tmpzval);
  190. +                               zval_ptr_dtor(tmpzval);
  191. +                               tmpzval = NULL;
  192. +                }
  193. +                
  194.                                 zend_hash_find(HASH_OF(filterparams), "small", sizeof("small"), (void **) &tmpzval);
  195.                         } else {
  196.                                 tmpzval = &filterparams;
  197.  -321,12 +368,12 @@
  198.                         if (tmpzval) {
  199.                                 SEPARATE_ZVAL(tmpzval);
  200.                                 convert_to_boolean_ex(tmpzval);
  201. -                               smallFootprint = Z_LVAL_PP(tmpzval);
  202. +                               data->small_footprint = Z_LVAL_PP(tmpzval);
  203.                                 zval_ptr_dtor(tmpzval);
  204.                         }
  205.                 }
  206.  
  207. -               status = BZ2_bzDecompressInit(&(data->strm), 0, smallFootprint);
  208. +               data->status = Uninitialised;
  209.                 fops = &php_bz2_decompress_ops;
  210.         } else if (strcasecmp(filtername, "bzip2.compress") == 0) {
  211.                 int blockSize100k = PHP_BZ2_FILTER_DEFAULT_BLOCKSIZE;