From 76cbcc7f663f18fe4cc6ae3de06261f67c9b3ff2 Mon Sep 17 00:00:00 2001 From: Scott MacVicar Date: Fri, 3 Jun 2011 00:12:22 +0000 Subject: [PATCH] Added fabled hex2bin() function --- NEWS | 1 + UPGRADING | 3 +- ext/standard/basic_functions.c | 5 +++ ext/standard/php_string.h | 1 + ext/standard/string.c | 62 ++++++++++++++++++++++++++++++++++ 5 files changed, 71 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 1eb6233e4bc..42e555de759 100644 --- a/NEWS +++ b/NEWS @@ -130,6 +130,7 @@ PHP NEWS - Improved core functions: . number_format() no longer truncates multibyte decimal points and thousand separators to the first byte. FR #53457. (Adam) + . Added hex2bin() function. (Scott) - Improved CURL extension: . Added support for CURLOPT_MAX_RECV_SPEED_LARGE and diff --git a/UPGRADING b/UPGRADING index df98caf6953..ef879668a49 100755 --- a/UPGRADING +++ b/UPGRADING @@ -358,10 +358,11 @@ UPGRADE NOTES - PHP X.Y - Core: - get_declared_traits() + - hex2bin() - http_response_code() - - trait_exists() - stream_set_chunk_size() - socket_import_stream() + - trait_exists() - LDAP: - ldap_control_paged_results() diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 9d2e656a6a9..b56f85caee5 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -2142,6 +2142,10 @@ ZEND_BEGIN_ARG_INFO(arginfo_bin2hex, 0) ZEND_ARG_INFO(0, data) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO(arginfo_hex2bin, 0) + ZEND_ARG_INFO(0, data) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO_EX(arginfo_strspn, 0, 0, 2) ZEND_ARG_INFO(0, str) ZEND_ARG_INFO(0, mask) @@ -2682,6 +2686,7 @@ ZEND_END_ARG_INFO() const zend_function_entry basic_functions[] = { /* {{{ */ PHP_FE(constant, arginfo_constant) PHP_FE(bin2hex, arginfo_bin2hex) + PHP_FE(hex2bin, arginfo_hex2bin) PHP_FE(sleep, arginfo_sleep) PHP_FE(usleep, arginfo_usleep) #if HAVE_NANOSLEEP diff --git a/ext/standard/php_string.h b/ext/standard/php_string.h index 71271cc6d92..23c703336ab 100644 --- a/ext/standard/php_string.h +++ b/ext/standard/php_string.h @@ -78,6 +78,7 @@ PHP_FUNCTION(chunk_split); PHP_FUNCTION(parse_str); PHP_FUNCTION(str_getcsv); PHP_FUNCTION(bin2hex); +PHP_FUNCTION(hex2bin); PHP_FUNCTION(similar_text); PHP_FUNCTION(strip_tags); PHP_FUNCTION(str_repeat); diff --git a/ext/standard/string.c b/ext/standard/string.c index 7cd986c51e7..44c5cd3b006 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -146,6 +146,46 @@ static char *php_bin2hex(const unsigned char *old, const size_t oldlen, size_t * } /* }}} */ +/* {{{ php_hex2bin + */ +static char *php_hex2bin(const unsigned char *old, const size_t oldlen, size_t *newlen) +{ + size_t target_length = oldlen >> 1; + register unsigned char *str = (unsigned char *)safe_emalloc(target_length, sizeof(char), 1); + size_t i, j; + for (i = j = 0; i < target_length; i++) { + char c = old[j++]; + if (c >= '0' && c <= '9') { + str[i] = (c - '0') << 4; + } else if (c >= 'a' && c <= 'f') { + str[i] = (c - 'a' + 10) << 4; + } else if (c >= 'A' && c <= 'F') { + str[i] = (c - 'A' + 10) << 4; + } else { + efree(str); + return NULL; + } + c = old[j++]; + if (c >= '0' && c <= '9') { + str[i] |= c - '0'; + } else if (c >= 'a' && c <= 'f') { + str[i] |= c - 'a' + 10; + } else if (c >= 'A' && c <= 'F') { + str[i] |= c - 'A' + 10; + } else { + efree(str); + return NULL; + } + } + str[target_length] = '\0'; + + if (newlen) + *newlen = target_length; + + return (char *)str; +} +/* }}} */ + #ifdef HAVE_LOCALECONV /* {{{ localeconv_r * glibc's localeconv is not reentrant, so lets make it so ... sorta */ @@ -214,6 +254,28 @@ PHP_FUNCTION(bin2hex) } /* }}} */ +/* {{{ proto string hex2bin(string data) + Converts the hex representation of data to binary */ +PHP_FUNCTION(hex2bin) +{ + char *result, *data; + size_t newlen; + int datalen; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &data, &datalen) == FAILURE) { + return; + } + + result = php_hex2bin((unsigned char *)data, datalen, &newlen); + + if (!result) { + RETURN_FALSE; + } + + RETURN_STRINGL(result, newlen, 0); +} +/* }}} */ + static void php_spn_common_handler(INTERNAL_FUNCTION_PARAMETERS, int behavior) /* {{{ */ { char *s11, *s22;