release 3.2.3
[m6w6/ext-http] / src / php_http_encoding_brotli.c
index f51775b1e180a47b4d208c139dfd9bab1fa2d7aa..dbea978db988d3f2944e10d2580a317b874e2a0f 100644 (file)
@@ -96,6 +96,7 @@ static ZEND_RESULT_CODE enbrotli_update(php_http_encoding_stream_t *s, const cha
                } else {
                        *encoded = NULL;
                        *encoded_len = 0;
+                       php_http_buffer_dtor(&out);
                }
                return SUCCESS;
        }
@@ -162,12 +163,19 @@ static ZEND_RESULT_CODE enbrotli_flush(php_http_encoding_stream_t *s, char **enc
 
 static ZEND_RESULT_CODE enbrotli_finish(php_http_encoding_stream_t *s, char **encoded, size_t *encoded_len)
 {
-       return enbrotli_flush_ex(s, BROTLI_OPERATION_FINISH, encoded, encoded_len);
+       ZEND_RESULT_CODE rc;
+
+       do {
+               rc = enbrotli_flush_ex(s, BROTLI_OPERATION_FINISH, encoded, encoded_len);
+       } while (SUCCESS == rc && !BrotliEncoderIsFinished(s->ctx));
+
+       return rc;
 }
 
 static zend_bool enbrotli_done(php_http_encoding_stream_t *s)
 {
-       return BrotliEncoderIsFinished(s->ctx);
+       return !(s->flags & PHP_HTTP_ENCODING_STREAM_DIRTY)
+                       || BrotliEncoderIsFinished(s->ctx);
 }
 
 static void enbrotli_dtor(php_http_encoding_stream_t *s)
@@ -227,6 +235,7 @@ static ZEND_RESULT_CODE debrotli_update(php_http_encoding_stream_t *s, const cha
                        *decoded = out.data;
                        *decoded_len = out.used;
                } else {
+                       php_http_buffer_dtor(&out);
                        *decoded = NULL;
                        *decoded_len = 0;
                }
@@ -235,13 +244,13 @@ static ZEND_RESULT_CODE debrotli_update(php_http_encoding_stream_t *s, const cha
 
        php_http_buffer_dtor(&out);
 
-       php_error_docref(NULL, E_WARNING, "Could not brotli decode data: %s", BrotliDecoderErrorString(rc));
+       php_error_docref(NULL, E_WARNING, "Could not brotli decode data: %s", BrotliDecoderErrorString(BrotliDecoderGetErrorCode(s->ctx)));
        return FAILURE;
 }
 
 static zend_bool debrotli_done(php_http_encoding_stream_t *s)
 {
-       return BrotliDecoderIsFinished(s->ctx);
+       return !BrotliDecoderIsUsed(s->ctx) || BrotliDecoderIsFinished(s->ctx);
 }
 
 static void debrotli_dtor(php_http_encoding_stream_t *s)
@@ -341,7 +350,7 @@ static PHP_METHOD(HttpEnbrotliStream, encode)
        size_t len;
        zend_long flags = PHP_HTTP_ENBROTLI_MODE_GENERIC | PHP_HTTP_ENBROTLI_WBITS_DEF | PHP_HTTP_ENBROTLI_LEVEL_DEF;
 
-       if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "s", &str, &len, &flags)) {
+       if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "s|l", &str, &len, &flags)) {
                char *enc_str = NULL;
                size_t enc_len;
 
@@ -388,10 +397,17 @@ static zend_function_entry php_http_debrotli_stream_methods[] = {
        EMPTY_FUNCTION_ENTRY
 };
 
+/* POS */
+const void *BrotliGetDictionary();
+const void *(*php_http_brotli_get_dictionary)();
+
 PHP_MINIT_FUNCTION(http_encoding_brotli)
 {
        zend_class_entry ce;
 
+       /* force link to libbrotlicommon, because their libraries don't */
+       php_http_brotli_get_dictionary = BrotliGetDictionary();
+
        memset(&ce, 0, sizeof(ce));
        INIT_NS_CLASS_ENTRY(ce, "http\\Encoding\\Stream", "Enbrotli", php_http_enbrotli_stream_methods);
        php_http_enbrotli_stream_class_entry = zend_register_internal_class_ex(&ce, php_http_get_encoding_stream_class_entry());