summaryrefslogtreecommitdiff
path: root/Zend/zend_strtod.c
diff options
context:
space:
mode:
Diffstat (limited to 'Zend/zend_strtod.c')
-rw-r--r--Zend/zend_strtod.c67
1 files changed, 58 insertions, 9 deletions
diff --git a/Zend/zend_strtod.c b/Zend/zend_strtod.c
index 3d133bfecd..d6e5ccf960 100644
--- a/Zend/zend_strtod.c
+++ b/Zend/zend_strtod.c
@@ -2037,11 +2037,7 @@ ret1:
return s0;
}
-/* F* VC6 */
-#if _MSC_VER <= 1300
-# pragma optimize( "", off )
-#endif
-ZEND_API double zend_strtod (CONST char *s00, char **se)
+ZEND_API double zend_strtod (CONST char *s00, CONST char **se)
{
int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign,
e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
@@ -2574,7 +2570,7 @@ retfree:
Bfree(delta);
ret:
if (se)
- *se = (char *)s;
+ *se = s;
result = sign ? -value(rv) : value(rv);
_THREAD_PRIVATE_MUTEX_LOCK(pow5mult_mutex);
@@ -2588,13 +2584,18 @@ ret:
return result;
}
-ZEND_API double zend_hex_strtod(const char *str, char **endptr)
+ZEND_API double zend_hex_strtod(const char *str, const char **endptr)
{
const char *s = str;
char c;
int any = 0;
double value = 0;
+ if (strlen(str) < 2) {
+ *endptr = str;
+ return 0.0;
+ }
+
if (*s == '0' && (s[1] == 'x' || s[1] == 'X')) {
s += 2;
}
@@ -2615,19 +2616,24 @@ ZEND_API double zend_hex_strtod(const char *str, char **endptr)
}
if (endptr != NULL) {
- *endptr = (char *)(any ? s - 1 : str);
+ *endptr = any ? s - 1 : str;
}
return value;
}
-ZEND_API double zend_oct_strtod(const char *str, char **endptr)
+ZEND_API double zend_oct_strtod(const char *str, const char **endptr)
{
const char *s = str;
char c;
double value = 0;
int any = 0;
+ if (strlen(str) < 1) {
+ *endptr = str;
+ return 0.0;
+ }
+
/* skip leading zero */
s++;
@@ -2643,6 +2649,49 @@ ZEND_API double zend_oct_strtod(const char *str, char **endptr)
}
if (endptr != NULL) {
+ *endptr = any ? s - 1 : str;
+ }
+
+ return value;
+}
+
+ZEND_API double zend_bin_strtod(const char *str, const char **endptr)
+{
+ const char *s = str;
+ char c;
+ double value = 0;
+ int any = 0;
+
+ if (strlen(str) < 2) {
+ *endptr = str;
+ return 0.0;
+ }
+
+ if ('0' == *s && ('b' == s[1] || 'B' == s[1])) {
+ s += 2;
+ }
+
+ while ((c = *s++)) {
+ /*
+ * Verify the validity of the current character as a base-2 digit. In
+ * the event that an invalid digit is found, halt the conversion and
+ * return the portion which has been converted thus far.
+ */
+ if ('0' == c || '1' == c)
+ value = value * 2 + c - '0';
+ else
+ break;
+
+ any = 1;
+ }
+
+ /*
+ * As with many strtoX implementations, should the subject sequence be
+ * empty or not well-formed, no conversion is performed and the original
+ * value of str is stored in *endptr, provided that endptr is not a null
+ * pointer.
+ */
+ if (NULL != endptr) {
*endptr = (char *)(any ? s - 1 : str);
}