php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Return to Bug #66399
Patch inconsistent-bin-hex-handling.patch revision 2014-01-03 14:25 UTC by krakjoe@php.net
revision 2014-01-03 14:15 UTC by krakjoe@php.net
revision 2014-01-03 14:13 UTC by krakjoe@php.net
revision 2014-01-03 13:39 UTC by krakjoe@php.net

Patch inconsistent-bin-hex-handling.patch for Strings related Bug #66399

Patch version 2014-01-03 14:25 UTC

Return to Bug #66399 | Download this patch
This patch renders other patches obsolete

Obsolete patches:

Patch Revisions:

Developer: krakjoe@php.net

diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c
index e862929..d6d5c9b 100644
--- a/Zend/zend_operators.c
+++ b/Zend/zend_operators.c
@@ -79,6 +79,24 @@ static const unsigned char tolower_map[256] = {
 		zend_binary_strncasecmp
  */
 
+static inline long zendi_strtol(const char *str, int base) {
+	long converted = 0L;
+	
+	if (str[0] == '0') {
+		if (str[1] != '\0' && str[2] != '\0') {
+			if (str[1] == 'x' || str[1] == 'X') {
+				return strtol(&str[2], NULL, 8);
+			} else {
+				if (str[1] == 'b' || str[1] == 'B') {
+					return  strtol(&str[2], NULL, 2);
+				}
+			}
+		}
+	}
+	
+	return strtol(str, NULL, base);
+}
+
 ZEND_API int zend_atoi(const char *str, int str_len) /* {{{ */
 {
 	int retval;
@@ -86,7 +104,7 @@ ZEND_API int zend_atoi(const char *str, int str_len) /* {{{ */
 	if (!str_len) {
 		str_len = strlen(str);
 	}
-	retval = strtol(str, NULL, 0);
+	retval = zendi_strtol(str, 0);
 	if (str_len>0) {
 		switch (str[str_len-1]) {
 			case 'g':
@@ -114,7 +132,7 @@ ZEND_API long zend_atol(const char *str, int str_len) /* {{{ */
 	if (!str_len) {
 		str_len = strlen(str);
 	}
-	retval = strtol(str, NULL, 0);
+	retval = zendi_strtol(str, 0);
 	if (str_len>0) {
 		switch (str[str_len-1]) {
 			case 'g':
@@ -263,7 +281,7 @@ ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC) /* {{{ */
 				Z_LVAL(holder) = zend_dval_to_lval(Z_DVAL_P(op));	\
 				break;												\
 			case IS_STRING:											\
-				Z_LVAL(holder) = strtol(Z_STRVAL_P(op), NULL, 10);	\
+				Z_LVAL(holder) = zendi_strtol(Z_STRVAL_P(op), 10);	\
 				break;												\
 			case IS_ARRAY:											\
 				Z_LVAL(holder) = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);	\
@@ -390,7 +408,7 @@ ZEND_API void convert_to_long_base(zval *op, int base) /* {{{ */
 			{
 				char *strval = Z_STRVAL_P(op);
 
-				Z_LVAL_P(op) = strtol(strval, NULL, base);
+				Z_LVAL_P(op) = zendi_strtol(strval, base);	
 				str_efree(strval);
 			}
 			break;
diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h
index 5c6fc86..dcb413b 100644
--- a/Zend/zend_operators.h
+++ b/Zend/zend_operators.h
@@ -156,11 +156,14 @@ static inline zend_uchar is_numeric_string_ex(const char *str, int length, long
 	}
 
 	if (ZEND_IS_DIGIT(*ptr)) {
-		/* Handle hex numbers
+		/* Handle hex/binary numbers
 		 * str is used instead of ptr to disallow signs and keep old behavior */
 		if (length > 2 && *str == '0' && (str[1] == 'x' || str[1] == 'X')) {
 			base = 16;
 			ptr += 2;
+		} else if (length > 2 && *str == '0' && (str[1] == 'b' || str[1] == 'B')) {
+			base = 2;
+			ptr += 2;
 		}
 
 		/* Skip any leading 0s */
diff --git a/Zend/zend_strtod.c b/Zend/zend_strtod.c
index 4546614..55bfa68 100644
--- a/Zend/zend_strtod.c
+++ b/Zend/zend_strtod.c
@@ -2063,7 +2063,7 @@ ZEND_API double zend_strtod (CONST char *s00, CONST char **se)
 	} else if (*s == '+') {
 		s++;
 	}
-
+	
 	if (*s == '\0') {
 		s = s00;
 		goto ret;
@@ -2074,7 +2074,16 @@ ZEND_API double zend_strtod (CONST char *s00, CONST char **se)
 		while(*++s == '0') ;
 		if (!*s)
 			goto ret;
+		
+		if (*s == 'x' || *s == 'X') {
+			if (s[1] != '\0')
+				return zend_hex_strtod(&s[1], se);
+		} else if (*s == 'b' || *s == 'B') {
+			if (s[1] != '\0')
+				return zend_bin_strtod(&s[1], se);
+		}
 	}
+	
 	s0 = s;
 	y = z = 0;
 	for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
@@ -2591,7 +2600,9 @@ ZEND_API double zend_hex_strtod(const char *str, const char **endptr)
 	double value = 0;
 
 	if (strlen(str) < 2) {
-		*endptr = str;
+		if (endptr != NULL) {
+			*endptr = str;
+		}
 		return 0.0;
 	}
 
@@ -2629,7 +2640,9 @@ ZEND_API double zend_oct_strtod(const char *str, const char **endptr)
 	int any = 0;
 
 	if (strlen(str) < 1) {
-		*endptr = str;
+		if (endptr != NULL) {
+			*endptr = str;
+		}
 		return 0.0;
 	}
 
@@ -2662,7 +2675,9 @@ ZEND_API double zend_bin_strtod(const char *str, const char **endptr)
 	int 		any = 0;
 
 	if (strlen(str) < 2) {
-		*endptr = str;
+		if (endptr != NULL) {
+			*endptr = str;
+		}
 		return 0.0;
 	}
 
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 16:01:28 2024 UTC