]> granicus.if.org Git - php/commitdiff
Allow hash()/hash_hmac() to accept ascii-unicode data,
authorSara Golemon <pollita@php.net>
Mon, 2 Oct 2006 01:38:05 +0000 (01:38 +0000)
committerSara Golemon <pollita@php.net>
Mon, 2 Oct 2006 01:38:05 +0000 (01:38 +0000)
Update tests to work in unicode.semantics mode.

20 files changed:
ext/hash/hash.c
ext/hash/tests/adler32.phpt
ext/hash/tests/crc32.phpt
ext/hash/tests/gost.phpt
ext/hash/tests/haval.phpt
ext/hash/tests/hmac-md5.phpt
ext/hash/tests/md2.phpt
ext/hash/tests/md4.phpt
ext/hash/tests/md5.phpt
ext/hash/tests/ripemd128.phpt
ext/hash/tests/ripemd160.phpt
ext/hash/tests/ripemd256.phpt
ext/hash/tests/ripemd320.phpt
ext/hash/tests/sha1.phpt
ext/hash/tests/sha256.phpt
ext/hash/tests/sha384.phpt
ext/hash/tests/sha512.phpt
ext/hash/tests/snefru.phpt
ext/hash/tests/tiger.phpt
ext/hash/tests/whirlpool.phpt

index ee526eeae1e6811f12e2e512bcfbf4ca313959b3..4910639c16d7a749bfc003a7059ca1b9a34f475f 100644 (file)
@@ -84,9 +84,12 @@ static void php_hash_do_hash(INTERNAL_FUNCTION_PARAMETERS, int isfilename)
                                RETURN_FALSE;
                        }
                } else {
-                       /* Unicode string passed for raw hashing */
-                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unicode strings can not be hashed.  Convert to a binary type.");
-                       RETURN_FALSE;
+                       data = zend_unicode_to_ascii((UChar*)data, data_len TSRMLS_CC);
+                       if (!data) {
+                               /* Non-ASCII Unicode string passed for raw hashing */
+                               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Binary or ASCII-Unicode string expected, non-ASCII-Unicode string received");
+                               RETURN_FALSE;
+                       }
                }
        }
 #else
@@ -94,25 +97,19 @@ static void php_hash_do_hash(INTERNAL_FUNCTION_PARAMETERS, int isfilename)
                return;
        }
 #endif
+       /* Assume failure */
+       RETVAL_FALSE;
 
        ops = php_hash_fetch_ops(algo, algo_len);
        if (!ops) {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown hashing algorithm: %s", algo);
-               if (data_type != IS_STRING) {
-                       /* Original filename was UNICODE, this string is a converted copy */
-                       efree(data);
-               }
-               RETURN_FALSE;
+               goto hash_done;
        }
        if (isfilename) {
                stream = php_stream_open_wrapper_ex(data, "rb", REPORT_ERRORS, NULL, DEFAULT_CONTEXT);
-               if (data_type != IS_STRING) {
-                       /* Original filename was UNICODE, this string is a converted copy */
-                       efree(data);
-               }
                if (!stream) {
                        /* Stream will report errors opening file */
-                       RETURN_FALSE;
+                       goto hash_done;
                }
        }
 
@@ -137,14 +134,27 @@ static void php_hash_do_hash(INTERNAL_FUNCTION_PARAMETERS, int isfilename)
 
        if (raw_output) {
                digest[ops->digest_size] = 0;
-               RETURN_STRINGL(digest, ops->digest_size, 0);
+
+               /* Raw output is binary only */
+               RETVAL_STRINGL(digest, ops->digest_size, 0);
        } else {
                char *hex_digest = safe_emalloc(ops->digest_size, 2, 1);
 
                php_hash_bin2hex(hex_digest, (unsigned char *) digest, ops->digest_size);
                hex_digest[2 * ops->digest_size] = 0;
                efree(digest);
-               RETURN_STRINGL(hex_digest, 2 * ops->digest_size, 0);
+
+               /* hexits can be binary or unicode */
+#if PHP_MAJOR_VERSION >= 6
+               RETVAL_RT_STRINGL(hex_digest, 2 * ops->digest_size, ZSTR_AUTOFREE);
+#else
+               RETVAL_STRINGL(hex_digest, 2 * ops->digest_size, 0);
+#endif
+       }
+
+hash_done:
+       if (data_type != IS_STRING) {
+               efree(data);
        }
 }
 
@@ -168,14 +178,14 @@ static void php_hash_do_hash_hmac(INTERNAL_FUNCTION_PARAMETERS, int isfilename)
 {
        char *algo, *data, *digest, *key, *K;
        int algo_len, data_len, key_len, i;
-       zend_uchar data_type = IS_STRING;
+       zend_uchar data_type = IS_STRING, key_type = IS_STRING;
        zend_bool raw_output = 0;
        php_hash_ops *ops;
        void *context;
        php_stream *stream = NULL;
 
 #if PHP_MAJOR_VERSION >= 6
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "stS|b", &algo, &algo_len, &data, &data_len, &data_type, &key, &key_len, &raw_output) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "stt|b", &algo, &algo_len, &data, &data_len, &data_type, &key, &key_len, &key_type, &raw_output) == FAILURE) {
                return;
        }
 
@@ -185,8 +195,22 @@ static void php_hash_do_hash_hmac(INTERNAL_FUNCTION_PARAMETERS, int isfilename)
                                RETURN_FALSE;
                        }
                } else {
-                       /* Unicode string passed for raw hashing */
-                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unicode strings can not be hashed.  Convert to a binary type.");
+                       data = zend_unicode_to_ascii((UChar*)data, data_len TSRMLS_CC);
+                       if (!data) {
+                               /* Non-ASCII Unicode string passed for raw hashing */
+                               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Binary or ASCII-Unicode string expected, non-ASCII-Unicode string received");
+                               RETURN_FALSE;
+                       }
+               }
+       }
+       if (key_type == IS_UNICODE) {
+               key = zend_unicode_to_ascii((UChar*)key, key_len TSRMLS_CC);
+               if (!key) {
+                       /* Non-ASCII Unicode key passed for raw hashing */
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Binary or ASCII-Unicode key expected, non-ASCII-Unicode key received");
+                       if (data_type == IS_UNICODE) {
+                               efree(data);
+                       }
                        RETURN_FALSE;
                }
        }
@@ -195,25 +219,19 @@ static void php_hash_do_hash_hmac(INTERNAL_FUNCTION_PARAMETERS, int isfilename)
                return;
        }
 #endif
+       /* Assume failure */
+       RETVAL_FALSE;
 
        ops = php_hash_fetch_ops(algo, algo_len);
        if (!ops) {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown hashing algorithm: %s", algo);
-               if (data_type != IS_STRING) {
-                       /* Original filename was UNICODE, this string is a converted copy */
-                       efree(data);
-               }
-               RETURN_FALSE;
+               goto hmac_done;
        }
        if (isfilename) {
                stream = php_stream_open_wrapper_ex(data, "rb", REPORT_ERRORS, NULL, DEFAULT_CONTEXT);
-               if (data_type != IS_STRING) {
-                       /* Original filename was UNICODE, this string is a converted copy */
-                       efree(data);
-               }
                if (!stream) {
                        /* Stream will report errors opening file */
-                       RETURN_FALSE;
+                       goto hmac_done;
                }
        }
 
@@ -227,6 +245,7 @@ static void php_hash_do_hash_hmac(INTERNAL_FUNCTION_PARAMETERS, int isfilename)
                /* Reduce the key first */
                ops->hash_update(context, (unsigned char *) key, key_len);
                ops->hash_final((unsigned char *) K, context);
+
                /* Make the context ready to start over */
                ops->hash_init(context);
        } else {
@@ -272,14 +291,30 @@ static void php_hash_do_hash_hmac(INTERNAL_FUNCTION_PARAMETERS, int isfilename)
 
        if (raw_output) {
                digest[ops->digest_size] = 0;
-               RETURN_STRINGL(digest, ops->digest_size, 0);
+
+               /* Raw output is binary only */
+               RETVAL_STRINGL(digest, ops->digest_size, 0);
        } else {
                char *hex_digest = safe_emalloc(ops->digest_size, 2, 1);
 
                php_hash_bin2hex(hex_digest, (unsigned char *) digest, ops->digest_size);
                hex_digest[2 * ops->digest_size] = 0;
                efree(digest);
-               RETURN_STRINGL(hex_digest, 2 * ops->digest_size, 0);
+
+               /* hexits can be binary or unicode */
+#if PHP_MAJOR_VERSION >= 6
+               RETVAL_RT_STRINGL(hex_digest, 2 * ops->digest_size, ZSTR_AUTOFREE);
+#else
+               RETVAL_STRINGL(hex_digest, 2 * ops->digest_size, 0);
+#endif
+       }
+
+hmac_done:
+       if (data_type != IS_STRING) {
+               efree(data);
+       }
+       if (key_type != IS_STRING) {
+               efree(key);
        }
 }
 
@@ -306,12 +341,13 @@ PHP_FUNCTION(hash_init)
 {
        char *algo, *key = NULL;
        int algo_len, key_len = 0, argc = ZEND_NUM_ARGS();
+       zend_uchar key_type;
        long options = 0;
        void *context;
        php_hash_ops *ops;
        php_hash_data *hash;
 
-       if (zend_parse_parameters(argc TSRMLS_CC, "s|ls", &algo, &algo_len, &options, &key, &key_len) == FAILURE) {
+       if (zend_parse_parameters(argc TSRMLS_CC, "s|lt", &algo, &algo_len, &options, &key, &key_len, &key_type) == FAILURE) {
                return;
        }
 
@@ -328,6 +364,15 @@ PHP_FUNCTION(hash_init)
                RETURN_FALSE;
        }
 
+       if (key_type == IS_UNICODE) {
+               key = zend_unicode_to_ascii((UChar*)key, key_len TSRMLS_CC);
+               if (!key) {
+                       /* Non-ASCII Unicode key passed for raw hashing */
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Binary or ASCII-Unicode key expected, non-ASCII-Unicode key received");
+                       RETURN_FALSE;
+               }
+       }
+
        context = emalloc(ops->context_size);
        ops->hash_init(context);
 
@@ -361,16 +406,14 @@ PHP_FUNCTION(hash_init)
                hash->key = (unsigned char *) K;
        }
 
+       if (key_type == IS_UNICODE) {
+               efree(key);
+       }
+
        ZEND_REGISTER_RESOURCE(return_value, hash, php_hash_le_hash);
 }
 /* }}} */
 
-#if PHP_MAJOR_VERSION >= 6
-# define PHP_HASH_UPDATE_ARGS "rS"
-#else
-# define PHP_HASH_UPDATE_ARGS "rs"
-#endif
-
 /* {{{ proto bool hash_update(resource context, string data) U
 Pump data into the hashing algorithm */
 PHP_FUNCTION(hash_update)
@@ -379,15 +422,35 @@ PHP_FUNCTION(hash_update)
        php_hash_data *hash;
        char *data;
        int data_len;
+       zend_uchar data_type = IS_STRING;
+
+#if PHP_MAJOR_VERSION >= 6
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rt", &zhash, &data, &data_len, &data_type) == FAILURE) {
+               return;
+       }
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, PHP_HASH_UPDATE_ARGS, &zhash, &data, &data_len) == FAILURE) {
+       if (data_type == IS_UNICODE) {
+               data = zend_unicode_to_ascii((UChar*)data, data_len TSRMLS_CC);
+               if (!data) {
+                       /* Non-ASCII Unicode string passed for raw hashing */
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Binary or ASCII-Unicode string expected, non-ASCII-Unicode string received");
+                       RETURN_FALSE;
+               }
+       }
+#else
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &zhash, &data, &data_len) == FAILURE) {
                return;
        }
+#endif
 
        ZEND_FETCH_RESOURCE(hash, php_hash_data*, &zhash, -1, PHP_HASH_RESNAME, php_hash_le_hash);
 
        hash->ops->hash_update(hash->context, (unsigned char *) data, data_len);
 
+       if (data_type != IS_STRING) {
+               efree(data);
+       }
+
        RETURN_TRUE;
 }
 /* }}} */
@@ -534,6 +597,7 @@ PHP_FUNCTION(hash_final)
        zend_list_delete(Z_RESVAL_P(zhash));
 
        if (raw_output) {
+               /* Raw output can only be binary */
                RETURN_STRINGL(digest, digest_len, 0);
        } else {
                char *hex_digest = safe_emalloc(digest_len,2,1);
@@ -541,7 +605,13 @@ PHP_FUNCTION(hash_final)
                php_hash_bin2hex(hex_digest, (unsigned char *) digest, digest_len);
                hex_digest[2 * digest_len] = 0;
                efree(digest);
-               RETURN_STRINGL(hex_digest, 2 * digest_len, 0);          
+
+               /* Hexits can be either binary or unicode */
+#if PHP_MAJOR_VERSION >= 6
+               RETURN_RT_STRINGL(hex_digest, 2 * digest_len, ZSTR_AUTOFREE);
+#else
+               RETURN_STRINGL(hex_digest, 2 * digest_len, 0);
+#endif
        }
 }
 /* }}} */
@@ -565,7 +635,7 @@ PHP_FUNCTION(hash_algos)
                (type = zend_hash_get_current_key_ex(&php_hash_hashtable, &str, &str_len, &idx, 0, &pos)) != HASH_KEY_NON_EXISTANT;
                zend_hash_move_forward_ex(&php_hash_hashtable, &pos)) {
 #if (PHP_MAJOR_VERSION >= 6)
-                       add_next_index_stringl(return_value, str.s, str_len-1, 1);
+                       add_next_index_ascii_stringl(return_value, str.s, str_len-1, 1);
 #else
                        add_next_index_stringl(return_value, str, str_len-1, 1);
 #endif
index 91dffd2bb46321d6bb86bd36090851650235da5e..11b6d25d345d791a2446be81eea7fc5bb2289456 100644 (file)
@@ -1,7 +1,7 @@
 --TEST--
 ADLER32
 --SKIPIF--
-<?php if (!extension_loaded('hash') || ini_get('unicode.semantics')) die('skip'); ?>
+<?php if (!extension_loaded('hash')) die('skip'); ?>
 --FILE--
 <?php
 echo hash('adler32', ''), "\n";
index 886286e8e68175c1fd31ab6b79728c27e617e0b9..a6ae3aefdf97a06b165c217e09774b2524fe509c 100644 (file)
@@ -1,7 +1,7 @@
 --TEST--
 CRC32
 --SKIPIF--
-<?php if (!extension_loaded('hash') || ini_get('unicode.semantics')) die('skip'); ?>
+<?php if (!extension_loaded('hash')) die('skip'); ?>
 --FILE--
 <?php
 echo hash('crc32', ''), "\n";
index a12e662409dcc3ac61f23ad64d040252ab186a37..378b5ce800a93a67262092dd71797e5bf553187c 100644 (file)
@@ -1,7 +1,7 @@
 --TEST--
 gost
 --SKIPIF--
-<?php if (!extension_loaded('hash') || ini_get('unicode.semantics')) die('skip'); ?>
+<?php if (!extension_loaded('hash')) die('skip'); ?>
 --FILE--
 <?php
 echo hash('gost', ''), "\n";
index d1e8ebc2afbd262a33df7824e47f004ec36d41d8..16db2fa6949afdbb8924c83b5707395e49fab60c 100644 (file)
@@ -1,7 +1,7 @@
 --TEST--
 haval algorithm (multi-vector, multi-pass, multi-width)
 --SKIPIF--
-<?php if(!extension_loaded("hash") || ini_get('unicode.semantics')) print "skip"; ?>
+<?php if(!extension_loaded("hash")) print "skip"; ?>
 --FILE--
 <?php
 echo "Empty String\n";
index d1b4d99c06e4b3af8c565423f0faaf18ff5dc84c..bfa7af46345792f2edde9d412820b9c18accc7db 100644 (file)
@@ -1,7 +1,8 @@
 --TEST--
 hmac-md5 algorithm
 --SKIPIF--
-<?php if(!extension_loaded("hash") || ini_get('unicode.semantics')) print "skip"; ?>
+<?php 
+if(!extension_loaded("hash")) print "skip"; ?>
 --FILE--
 <?php
 /* Test Vectors from RFC 2104 */
@@ -18,3 +19,8 @@ echo hash_hmac('md5', str_repeat(chr(0xDD), 50), str_repeat(chr(0xAA), 16)) . "\
 9294727a3638bb1c13f48ef8158bfc9d
 750c783e6ab0b503eaa86e310a5db738
 56be34521d144c88dbb8c733f0e8b3f6
+--UEXPECTF--
+9294727a3638bb1c13f48ef8158bfc9d
+750c783e6ab0b503eaa86e310a5db738
+
+Warning: hash_hmac(): Binary or ASCII-Unicode string expected, non-ASCII-Unicode string received in %s/tests/hmac-md5.php on line %d
index 4ccbfbd2c40dc4b3e3e56d256ae9f3d056305194..c98ad34054e1030f5874efb6c6288fbde226f093 100644 (file)
@@ -1,7 +1,7 @@
 --TEST--
 md2 algorithm
 --SKIPIF--
-<?php if(!extension_loaded("hash") || ini_get('unicode.semantics')) print "skip"; ?>
+<?php if(!extension_loaded("hash")) print "skip"; ?>
 --FILE--
 <?php
 echo hash('md2', '') . "\n";
index 362fdc0771a1cc745a152e7d63c064fac0b7c08a..8d90429076d90acdca3380856e78b7e78b125d95 100644 (file)
@@ -1,7 +1,7 @@
 --TEST--
 md4 algorithm
 --SKIPIF--
-<?php if(!extension_loaded("hash") || ini_get('unicode.semantics')) print "skip"; ?>
+<?php if(!extension_loaded("hash")) print "skip"; ?>
 --FILE--
 <?php
 /* RFC 1320 vectors */
index a0e205d73e47b457949a301d0396fbadd70aeb6b..d56f0b91a0f76cd92f1f10e4b4a48fab33c5e3ad 100644 (file)
@@ -1,7 +1,7 @@
 --TEST--
 md5 algorithm
 --SKIPIF--
-<?php if(!extension_loaded("hash") || ini_get('unicode.semantics')) print "skip"; ?>
+<?php if(!extension_loaded("hash")) print "skip"; ?>
 --FILE--
 <?php
 echo hash('md5', '') . "\n";
index 4c10baf805005cf3205f712a6e77f3932310bff6..e7473e316cab264b2b7673fa3719511f826b52a4 100644 (file)
@@ -1,7 +1,7 @@
 --TEST--
 ripemd128 algorithm
 --SKIPIF--
-<?php if(!extension_loaded("hash") || ini_get('unicode.semantics')) print "skip"; ?>
+<?php if(!extension_loaded("hash")) print "skip"; ?>
 --FILE--
 <?php
 echo hash('ripemd128', '') . "\n";
index 04d5bb9f6cf54aea4f30f266c02ba8c9454f713b..8fe7b05296a64f5d567fcd9f75ca40cfd1474806 100644 (file)
@@ -1,7 +1,7 @@
 --TEST--
 ripemd160 algorithm
 --SKIPIF--
-<?php if(!extension_loaded("hash") || ini_get('unicode.semantics')) print "skip"; ?>
+<?php if(!extension_loaded("hash")) print "skip"; ?>
 --FILE--
 <?php
 echo hash('ripemd160', '') . "\n";
index 00aaf7632aca90c22e6045654ccf9c50bb95c8ce..6fc23794a5df2359971864f4c57affc55589eda5 100644 (file)
@@ -1,7 +1,7 @@
 --TEST--
 ripemd256 algorithm
 --SKIPIF--
-<?php if(!extension_loaded("hash") || ini_get('unicode.semantics')) print "skip"; ?>
+<?php if(!extension_loaded("hash")) print "skip"; ?>
 --FILE--
 <?php
 echo hash('ripemd256', '') . "\n";
index 800e31084d4011c87cd6b19163c9f6bb69f6241e..152c922d5d9320d73054c2c0b55d413031bb8410 100644 (file)
@@ -1,7 +1,7 @@
 --TEST--
 ripemd320 algorithm
 --SKIPIF--
-<?php if(!extension_loaded("hash") || ini_get('unicode.semantics')) print "skip"; ?>
+<?php if(!extension_loaded("hash")) print "skip"; ?>
 --FILE--
 <?php
 echo hash('ripemd320', '') . "\n";
index 4e98a57ebcccdc158ac81292ee100a535e8698e7..b19378165331b860c99b5235845716ed1af40649 100644 (file)
@@ -1,7 +1,7 @@
 --TEST--
 sha1 algorithm
 --SKIPIF--
-<?php if(!extension_loaded("hash") || ini_get('unicode.semantics')) print "skip"; ?>
+<?php if(!extension_loaded("hash")) print "skip"; ?>
 --FILE--
 <?php
 echo hash('sha1', '') . "\n";
index bfeec455a9ddb94df45b47ec45d3124d0b49a98b..04b1c11abd314b0e67dd15757953a4beeff2e0ce 100644 (file)
@@ -1,7 +1,7 @@
 --TEST--
 sha256 algorithm
 --SKIPIF--
-<?php if(!extension_loaded("hash") || ini_get('unicode.semantics')) print "skip"; ?>
+<?php if(!extension_loaded("hash")) print "skip"; ?>
 --FILE--
 <?php
 echo hash('sha256', '') . "\n";
index 739dcb6b69af94093b33a5bec98df2e031570944..e5be2ab2747f56fa71f5d0ece5bbce33eadb60a0 100644 (file)
@@ -1,7 +1,7 @@
 --TEST--
 sha384 algorithm
 --SKIPIF--
-<?php if(!extension_loaded("hash") || ini_get('unicode.semantics')) print "skip"; ?>
+<?php if(!extension_loaded("hash")) print "skip"; ?>
 --FILE--
 <?php
 echo hash('sha384', '') . "\n";
index e5959699998235aa436afa21398630030ac96a6e..93fbb20d635a4751fac8b657641366392e7ad159 100644 (file)
@@ -1,7 +1,7 @@
 --TEST--
 sha512 algorithm
 --SKIPIF--
-<?php if(!extension_loaded("hash") || ini_get('unicode.semantics')) print "skip"; ?>
+<?php if(!extension_loaded("hash")) print "skip"; ?>
 --FILE--
 <?php
 echo hash('sha512', '') . "\n";
index daf177020018050b3619d617ab5282867249ec7f..3aba3b31d7c436a9670232ce1eba27e2c08c6d02 100644 (file)
@@ -1,7 +1,7 @@
 --TEST--
 snefru
 --SKIPIF--
-<?php if (!extension_loaded('hash') || ini_get('unicode.semantics')) die('skip'); ?>
+<?php if (!extension_loaded('hash')) die('skip'); ?>
 --FILE--
 <?php
 echo hash('snefru', ''), "\n";
index b24ebef04810293727f37fc8ee80d7758e90b054..7f7620b3ff50d7877614ad9595bd3cbc7d52a109 100644 (file)
@@ -1,7 +1,7 @@
 --TEST--
 tiger
 --SKIPIF--
-<?php if (!extension_loaded('hash') || ini_get('unicode.semantics')) die('skip'); ?>
+<?php if (!extension_loaded('hash')) die('skip'); ?>
 --FILE--
 <?php
 echo hash('tiger192,3', ''),"\n";
index 83eb01a9542229b015055e65bf07d5ae44abc95e..c8e51bbb7119d30b28c706790495c1c669372bd2 100644 (file)
@@ -1,7 +1,7 @@
 --TEST--
 whirlpool
 --SKIPIF--
-<?php if (!extension_loaded('hash') || ini_get('unicode.semantics')) die('skip'); ?>
+<?php if (!extension_loaded('hash')) die('skip'); ?>
 --FILE--
 <?php
 echo hash('whirlpool', ''), "\n";