- allow negative time offsets
[m6w6/ext-http] / http_encoding_api.c
index 432cf15dc0644946ff58488984973029f68d3324..28ea4232d2627dcf2d5d5e61e51f6ec1ac0eafe1 100644 (file)
@@ -216,7 +216,7 @@ inline STATUS http_verify_gzencode_buffer(const char *data, size_t data_len, con
                http_error_ex(error_level TSRMLS_CC, HTTP_E_ENCODING, "Unrecognized compression format (%d)", (int) (data[2] & 0xFF));
                /* still try to decode */
        }
-       if ((data[3] & 0x3) == 0x3) {
+       if ((data[3] & 0x4) == 0x4) {
                if (data_len < offset + 2) {
                        goto really_bad_gzip_header;
                }
@@ -226,14 +226,14 @@ inline STATUS http_verify_gzencode_buffer(const char *data, size_t data_len, con
                offset += (unsigned) ((data[offset] & 0xFF) << 8);
                offset += 1;
        }
-       if ((data[3] & 0x4) == 0x4) {
+       if ((data[3] & 0x8) == 0x8) {
                if (data_len <= offset) {
                        goto really_bad_gzip_header;
                }
                /* there's a file name */
                offset += strlen(&data[offset]) + 1 /*NUL*/;
        }
-       if ((data[3] & 0x5) == 0x5) {
+       if ((data[3] & 0x10) == 0x10) {
                if (data_len <= offset) {
                        goto really_bad_gzip_header;
                }
@@ -261,6 +261,11 @@ inline STATUS http_verify_gzencode_buffer(const char *data, size_t data_len, con
                }
        }
        
+       if (data_len < offset + 8) {
+               http_error(error_level TSRMLS_CC, HTTP_E_ENCODING, "Missing or truncated GZIP footer");
+               return FAILURE;
+       }
+       
        if (encoded) {
                *encoded = data + offset;
        }
@@ -303,6 +308,71 @@ inline STATUS http_verify_gzdecode_buffer(const char *data, size_t data_len, con
        return status;
 }
 
+PHP_HTTP_API STATUS _http_encode(http_encoding_type type, int level, const char *data, size_t data_len, char **encoded, size_t *encoded_len TSRMLS_DC)
+{
+       STATUS status = SUCCESS;
+       
+       switch (type)
+       {
+               case HTTP_ENCODING_ANY:
+               case HTTP_ENCODING_GZIP:
+                       status = http_encoding_gzencode(level, data, data_len, encoded, encoded_len);
+               break;
+               
+               case HTTP_ENCODING_DEFLATE:
+                       status = http_encoding_deflate(level, data, data_len, encoded, encoded_len);
+               break;
+               
+               case HTTP_ENCODING_COMPRESS:
+                       status = http_encoding_compress(level, data, data_len, encoded, encoded_len);
+               break;
+               
+               case HTTP_ENCODING_NONE:
+               default:
+                       *encoded = estrndup(data, data_len);
+                       *encoded_len = data_len;
+               break;
+       }
+       
+       return status;
+}
+
+PHP_HTTP_API STATUS _http_decode(http_encoding_type type, const char *data, size_t data_len, char **decoded, size_t *decoded_len TSRMLS_DC)
+{
+       STATUS status = SUCCESS;
+       
+       switch (type)
+       {
+               case HTTP_ENCODING_ANY:
+                       if (    SUCCESS != http_encoding_gzdecode(data, data_len, decoded, decoded_len) &&
+                                       SUCCESS != http_encoding_inflate(data, data_len, decoded, decoded_len) &&
+                                       SUCCESS != http_encoding_uncompress(data, data_len, decoded, decoded_len)) {
+                               status = FAILURE;
+                       }
+               break;
+               
+               case HTTP_ENCODING_GZIP:
+                       status = http_encoding_gzdecode(data, data_len, decoded, decoded_len);
+               break;
+               
+               case HTTP_ENCODING_DEFLATE:
+                       status = http_encoding_inflate(data, data_len, decoded, decoded_len);
+               break;
+               
+               case HTTP_ENCODING_COMPRESS:
+                       status = http_encoding_uncompress(data, data_len, decoded, decoded_len);
+               break;
+               
+               case HTTP_ENCODING_NONE:
+               default:
+                       *decoded = estrndup(data, data_len);
+                       *decoded_len = data_len;
+               break;
+       }
+       
+       return status;
+}
+
 PHP_HTTP_API STATUS _http_encoding_gzencode(int level, const char *data, size_t data_len, char **encoded, size_t *encoded_len TSRMLS_DC)
 {
        z_stream Z;