- fix HttpQueryString::xlate()
authorMichael Wallner <mike@php.net>
Sun, 19 Mar 2006 12:05:42 +0000 (12:05 +0000)
committerMichael Wallner <mike@php.net>
Sun, 19 Mar 2006 12:05:42 +0000 (12:05 +0000)
- add xlate test
- fixup old tests for encoded square brackets

http_querystring_object.c
package2.xml
tests/HttpQueryString_001.phpt
tests/HttpQueryString_002.phpt
tests/HttpQueryString_003.phpt [new file with mode: 0644]

index 6a3f0f30ff9cae302c3eb2a1f597cfdc1ea6e61f..dbfd85b15a8d94bef386a71256316a51219ccb95 100644 (file)
@@ -193,6 +193,64 @@ static inline int _http_querystring_modify_array(zval *qarray, zval *params TSRM
 static inline int _http_querystring_modify(zval *qarray, zval *params TSRMLS_DC);
 #define http_querystring_get(o, t, n, l, def, del, r) _http_querystring_get((o), (t), (n), (l), (def), (del), (r) TSRMLS_CC)
 static inline void _http_querystring_get(zval *this_ptr, int type, char *name, uint name_len, zval *defval, zend_bool del, zval *return_value TSRMLS_DC);
+#ifdef HAVE_ICONV
+#define http_querystring_xlate(a, p, ie, oe) _http_querystring_xlate((a), (p), (ie), (oe) TSRMLS_CC)
+static inline int _http_querystring_xlate(zval *array, zval *param, const char *ie, const char *oe TSRMLS_DC)
+{
+       HashPosition pos;
+       zval **entry = NULL;
+       char *xlate_str = NULL, *xkey, *kstr = NULL;
+       size_t xlate_len = 0, xlen;
+       uint klen = 0;
+       ulong kidx = 0;
+       
+       FOREACH_KEYLENVAL(pos, param, kstr, klen, kidx, entry) {
+               if (kstr) {
+                       if (PHP_ICONV_ERR_SUCCESS != php_iconv_string(kstr, klen-1, &xkey, &xlen, oe, ie)) {
+                               http_error_ex(HE_WARNING, HTTP_E_QUERYSTRING, "Failed to convert '%.*s' from '%s' to '%s'", klen-1, kstr, ie, oe);
+                               return FAILURE;
+                       }
+               }
+               
+               if (Z_TYPE_PP(entry) == IS_STRING) {
+                       if (PHP_ICONV_ERR_SUCCESS != php_iconv_string(Z_STRVAL_PP(entry), Z_STRLEN_PP(entry), &xlate_str, &xlate_len, oe, ie)) {
+                               if (kstr) {
+                                       efree(xkey);
+                               }
+                               http_error_ex(HE_WARNING, HTTP_E_QUERYSTRING, "Failed to convert '%.*s' from '%s' to '%s'", Z_STRLEN_PP(entry), Z_STRVAL_PP(entry), ie, oe);
+                               return FAILURE;
+                       }
+                       if (kstr) {
+                               add_assoc_stringl_ex(array, xkey, xlen+1, xlate_str, xlate_len, 0);
+                       } else {
+                               add_index_stringl(array, kidx, xlate_str, xlate_len, 0);
+                       }
+               } else if (Z_TYPE_PP(entry) == IS_ARRAY) {
+                       zval *subarray;
+                       
+                       MAKE_STD_ZVAL(subarray);
+                       array_init(subarray);
+                       if (kstr) {
+                               add_assoc_zval_ex(array, xkey, xlen+1, subarray);
+                       } else {
+                               add_index_zval(array, kidx, subarray);
+                       }
+                       if (SUCCESS != http_querystring_xlate(subarray, *entry, ie, oe)) {
+                               if (kstr) {
+                                       efree(xkey);
+                               }
+                               return FAILURE;
+                       }
+               }
+               
+               if (kstr) {
+                       kstr = NULL;
+                       efree(xkey);
+               }
+       }
+       return SUCCESS;
+}
+#endif /* HAVE_ICONV */
 #ifndef WONKY
 #define http_querystring_instantiate(g) _http_querystring_instantiate((g) TSRMLS_CC)
 static inline zval *_http_querystring_instantiate(zend_bool global TSRMLS_DC)
@@ -368,9 +426,10 @@ PHP_METHOD(HttpQueryString, __construct)
                                GET_PROP(queryArray)->is_ref = 1;
                                GET_PROP(queryString)->is_ref = 1;
                                
-                               if (params && http_querystring_modify(GET_PROP(queryArray), params)) {
-                                       http_querystring_update(GET_PROP(queryArray), GET_PROP(queryString));
+                               if (params) {
+                                       http_querystring_modify(GET_PROP(queryArray), params);
                                }
+                               http_querystring_update(GET_PROP(queryArray), GET_PROP(queryString));
                        }
                } else {
                        qarray = ecalloc(1, sizeof(zval));
@@ -546,10 +605,10 @@ HTTP_QUERYSTRING_GETTER(getObject, IS_OBJECT);
  */
 PHP_METHOD(HttpQueryString, xlate)
 {
-       char *ie, *oe, *er = NULL;
+       char *ie, *oe;
        int ie_len, oe_len;
-       size_t er_len = 0;
-       zval *qa, *qs;
+       zval xa, *qa, *qs;
+       STATUS rs;
        
        if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &ie, &ie_len, &oe, &oe_len)) {
                RETURN_FALSE;
@@ -557,17 +616,17 @@ PHP_METHOD(HttpQueryString, xlate)
        
        qa = GET_PROP(queryArray);
        qs = GET_PROP(queryString);
-       Z_STRLEN_P(qs) = php_url_decode(Z_STRVAL_P(qs), Z_STRLEN_P(qs));
-       if (PHP_ICONV_ERR_SUCCESS == php_iconv_string(Z_STRVAL_P(qs), (size_t) Z_STRLEN_P(qs), &er, &er_len, oe, ie)) {
-               efree(Z_STRVAL_P(qs));
-               ZVAL_STRINGL(qs, er, er_len, 0);
-               http_querystring_modify(qa, qs);
-               RETVAL_TRUE;
-       } else {
-               http_error_ex(HE_WARNING, HTTP_E_QUERYSTRING, "Failed to convert '%.*s' from '%s' to '%s'", Z_STRLEN_P(qs), Z_STRVAL_P(qs), ie, oe);
-               RETVAL_FALSE;
+       INIT_PZVAL(&xa);
+       array_init(&xa);
+       
+       if (SUCCESS == (rs = http_querystring_xlate(&xa, qa, ie, oe))) {
+               zend_hash_clean(Z_ARRVAL_P(qa));
+               zend_hash_copy(Z_ARRVAL_P(qa), Z_ARRVAL(xa), (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
+               http_querystring_update(qa, qs);
        }
-       http_querystring_update(qa, qs);
+       zval_dtor(&xa);
+       
+       RETURN_SUCCESS(rs);
 }
 /* }}} */
 #endif /* HAVE_ICONV */
index c2eda4e1bd82f2eacb056268046b45fab975acc7..91a873838b4ad73bf12f9aae333392cc82aa7eb8 100644 (file)
@@ -47,7 +47,8 @@ HttpResponse
  <license>BSD, revised</license>
  <notes><![CDATA[
 * Fixed possible crash in HttpQueryString if the SAPI does not have a treat_data function registered.
-* Fixed http_build_str() to urlencode brackets ("[]").
+* Fixed http_build_str() to urlencode square brackets ("[]").
+* Fixed HttpQueryString::xlate()
 * Fixed builds where include/php/ext/iconv does not have php_have_*.h files
 * Fixed PHP-4 build.
 ]]></notes>
@@ -185,6 +186,7 @@ HttpResponse
     <file role="test" name="HttpMessage_007.phpt"/>
     <file role="test" name="HttpQueryString_001.phpt"/>
     <file role="test" name="HttpQueryString_002.phpt"/>
+    <file role="test" name="HttpQueryString_003.phpt"/>
     <file role="test" name="HttpRequest_001.phpt"/>
     <file role="test" name="HttpRequest_002.phpt"/>
     <file role="test" name="HttpRequest_003.phpt"/>
index e1afcc039c1bcb6172b8d39d3c6f51ed844557d9..6a9b5c80bfa5487e36c2d7d4a53fd78ae0be8157 100644 (file)
@@ -38,7 +38,7 @@ echo "Done\n";
 ?>
 --EXPECTF--
 %sTEST
-string(30) "a=b&c=3.4&r[0]=1&r[1]=2&r[2]=3"
+string(42) "a=b&c=3.4&r%5B0%5D=1&r%5B1%5D=2&r%5B2%5D=3"
 NULL
 string(1) "b"
 int(0)
@@ -92,7 +92,7 @@ object(HttpQueryString)#1 (2) {
     }
   }
   ["queryString:private"]=>
-  &string(33) "c=3.4&r[0]=1&r[1]=2&r[2]=3&z[0]=2"
+  &string(49) "c=3.4&r%5B0%5D=1&r%5B1%5D=2&r%5B2%5D=3&z%5B0%5D=2"
 }
 array(3) {
   ["c"]=>
@@ -112,5 +112,5 @@ array(3) {
     string(1) "2"
   }
 }
-string(33) "c=3.4&r[0]=1&r[1]=2&r[2]=3&z[0]=2"
+string(49) "c=3.4&r%5B0%5D=1&r%5B1%5D=2&r%5B2%5D=3&z%5B0%5D=2"
 Done
\ No newline at end of file
index 867c700b50d72410a44eceee1c947a31aa24823d..63d143e88ceb6615f9904766eb5b6fbee4a8bb0e 100644 (file)
@@ -34,7 +34,7 @@ echo "Done\n";
 ?>
 --EXPECTF--
 %sTEST
-string(30) "a=b&c=3.4&r[0]=1&r[1]=2&r[2]=3"
+string(42) "a=b&c=3.4&r%5B0%5D=1&r%5B1%5D=2&r%5B2%5D=3"
 NULL
 string(1) "b"
 int(0)
@@ -88,7 +88,7 @@ object(HttpQueryString)#1 (2) {
     }
   }
   ["queryString:private"]=>
-  string(33) "c=3.4&r[0]=1&r[1]=2&r[2]=3&z[0]=2"
+  string(49) "c=3.4&r%5B0%5D=1&r%5B1%5D=2&r%5B2%5D=3&z%5B0%5D=2"
 }
 array(3) {
   ["a"]=>
diff --git a/tests/HttpQueryString_003.phpt b/tests/HttpQueryString_003.phpt
new file mode 100644 (file)
index 0000000..f90a582
--- /dev/null
@@ -0,0 +1,24 @@
+--TEST--
+HttpQueryString xlate
+--SKIPIF--
+<?php
+include 'skip.inc';
+checkmin(5);
+checkext('iconv');
+?>
+--FILE--
+<?php
+echo "-TEST\n";
+$qs = new HttpQueryString(false, "ä[0]=ü&ö[a]=ß");
+var_dump($qs->get());
+$qs->xlate("latin1", "utf8");
+var_dump($qs->get());
+$qs->xlate("utf8", "latin1");
+var_dump($qs->get());
+echo "Done\n";
+--EXPECTF--
+%sTEST
+string(29) "%E4%5B0%5D=%FC&%F6%5Ba%5D=%DF"
+string(41) "%C3%A4%5B0%5D=%C3%BC&%C3%B6%5Ba%5D=%C3%9F"
+string(29) "%E4%5B0%5D=%FC&%F6%5Ba%5D=%DF"
+Done