summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--tests/custom/04_bugs/28_null_equality31
-rw-r--r--types.c9
2 files changed, 38 insertions, 2 deletions
diff --git a/tests/custom/04_bugs/28_null_equality b/tests/custom/04_bugs/28_null_equality
new file mode 100644
index 0000000..b71a3b1
--- /dev/null
+++ b/tests/custom/04_bugs/28_null_equality
@@ -0,0 +1,31 @@
+When comparing `null` with another value for loose equality or inequality,
+the values `0`, `0.0`, `false` and `"0x0"` (any string interpreted as
+numeric null) were incorrectly treated as equal.
+
+-- Testcase --
+{{ null == 0 }}
+{{ null == 0.0 }}
+{{ null == false }}
+{{ null == "0x0" }}
+{{ null == null }}
+
+{{ null != 0 }}
+{{ null != 0.0 }}
+{{ null != false }}
+{{ null != "0x0" }}
+{{ null != null }}
+-- End --
+
+-- Expect stdout --
+false
+false
+false
+false
+true
+
+true
+true
+true
+true
+false
+-- End --
diff --git a/types.c b/types.c
index 68eba42..5ea1180 100644
--- a/types.c
+++ b/types.c
@@ -1918,8 +1918,13 @@ ucv_compare(int how, uc_value_t *v1, uc_value_t *v2, int *deltap)
double d1, d2;
int8_t delta;
- /* if both operands are strings, compare bytewise */
- if (t1 == UC_STRING && t2 == UC_STRING) {
+ /* at least one operand is null and we compare for equality or inequality ... */
+ if ((!v1 || !v2) && (how == I_EQ || how == I_NE)) {
+ delta = (v1 != v2);
+ }
+
+ /* ... otherwise if both operands are strings, compare bytewise ... */
+ else if (t1 == UC_STRING && t2 == UC_STRING) {
delta = strcmp(ucv_string_get(v1), ucv_string_get(v2));
}