summaryrefslogtreecommitdiff
path: root/Zend/zend_operators.c
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2018-01-16 17:24:00 +0300
committerDmitry Stogov <dmitry@zend.com>2018-01-16 17:24:00 +0300
commit19676fdf55ac2fa473ab8095fee06b5bdd299aee (patch)
treec41ad82638118bea54d44ec8971cf93e05ead0c3 /Zend/zend_operators.c
parente229e7b657af10996669793ac589f216aa0cc3d0 (diff)
downloadphp-git-19676fdf55ac2fa473ab8095fee06b5bdd299aee.tar.gz
Added zendi_smart_streq() for smart string equality check
Diffstat (limited to 'Zend/zend_operators.c')
-rw-r--r--Zend/zend_operators.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c
index a8af4bf3f7..dc6f2d6352 100644
--- a/Zend/zend_operators.c
+++ b/Zend/zend_operators.c
@@ -2791,6 +2791,54 @@ ZEND_API int ZEND_FASTCALL zend_binary_zval_strncasecmp(zval *s1, zval *s2, zval
}
/* }}} */
+ZEND_API int ZEND_FASTCALL zendi_smart_streq(zend_string *s1, zend_string *s2) /* {{{ */
+{
+ int ret1, ret2;
+ int oflow1, oflow2;
+ zend_long lval1 = 0, lval2 = 0;
+ double dval1 = 0.0, dval2 = 0.0;
+
+ if ((ret1 = is_numeric_string_ex(s1->val, s1->len, &lval1, &dval1, 0, &oflow1)) &&
+ (ret2 = is_numeric_string_ex(s2->val, s2->len, &lval2, &dval2, 0, &oflow2))) {
+#if ZEND_ULONG_MAX == 0xFFFFFFFF
+ if (oflow1 != 0 && oflow1 == oflow2 && dval1 - dval2 == 0. &&
+ ((oflow1 == 1 && dval1 > 9007199254740991. /*0x1FFFFFFFFFFFFF*/)
+ || (oflow1 == -1 && dval1 < -9007199254740991.))) {
+#else
+ if (oflow1 != 0 && oflow1 == oflow2 && dval1 - dval2 == 0.) {
+#endif
+ /* both values are integers overflown to the same side, and the
+ * double comparison may have resulted in crucial accuracy lost */
+ goto string_cmp;
+ }
+ if ((ret1 == IS_DOUBLE) || (ret2 == IS_DOUBLE)) {
+ if (ret1 != IS_DOUBLE) {
+ if (oflow2) {
+ /* 2nd operand is integer > LONG_MAX (oflow2==1) or < LONG_MIN (-1) */
+ return 0;
+ }
+ dval1 = (double) lval1;
+ } else if (ret2 != IS_DOUBLE) {
+ if (oflow1) {
+ return 0;
+ }
+ dval2 = (double) lval2;
+ } else if (dval1 == dval2 && !zend_finite(dval1)) {
+ /* Both values overflowed and have the same sign,
+ * so a numeric comparison would be inaccurate */
+ goto string_cmp;
+ }
+ return dval1 == dval2;
+ } else { /* they both have to be long's */
+ return lval1 == lval2;
+ }
+ } else {
+string_cmp:
+ return zend_string_equal_content(s1, s2);
+ }
+}
+/* }}} */
+
ZEND_API int ZEND_FASTCALL zendi_smart_strcmp(zend_string *s1, zend_string *s2) /* {{{ */
{
int ret1, ret2;