shithub: libmujs

Download patch

ref: 32ac46df1537af92a08377fe4ac31b55fa759a59
parent: 7562052e872fe33f55834e1b72c8e4969fb83b1c
author: Tor Andersson <tor@ccxvii.net>
date: Wed Feb 26 10:58:02 EST 2014

Fix relational equality with NaN.

--- a/js.h
+++ b/js.h
@@ -159,7 +159,7 @@
 void js_replace(js_State* J, int idx);
 
 void js_concat(js_State *J);
-int js_compare(js_State *J);
+int js_compare(js_State *J, int *okay);
 int js_equal(js_State *J);
 int js_strictequal(js_State *J);
 int js_instanceof(js_State *J);
--- a/jsrun.c
+++ b/jsrun.c
@@ -1000,7 +1000,7 @@
 	js_Object *obj;
 	double x, y;
 	unsigned int ux, uy;
-	int ix, iy;
+	int ix, iy, okay;
 	int b;
 
 	while (1) {
@@ -1315,10 +1315,10 @@
 
 		/* Relational operators */
 
-		case OP_LT: b = js_compare(J); js_pop(J, 2); js_pushboolean(J, b < 0); break;
-		case OP_GT: b = js_compare(J); js_pop(J, 2); js_pushboolean(J, b > 0); break;
-		case OP_LE: b = js_compare(J); js_pop(J, 2); js_pushboolean(J, b <= 0); break;
-		case OP_GE: b = js_compare(J); js_pop(J, 2); js_pushboolean(J, b >= 0); break;
+		case OP_LT: b = js_compare(J, &okay); js_pop(J, 2); js_pushboolean(J, okay && b < 0); break;
+		case OP_GT: b = js_compare(J, &okay); js_pop(J, 2); js_pushboolean(J, okay && b > 0); break;
+		case OP_LE: b = js_compare(J, &okay); js_pop(J, 2); js_pushboolean(J, okay && b <= 0); break;
+		case OP_GE: b = js_compare(J, &okay); js_pop(J, 2); js_pushboolean(J, okay && b >= 0); break;
 
 		case OP_INSTANCEOF:
 			b = js_instanceof(J);
--- a/jsvalue.c
+++ b/jsvalue.c
@@ -368,16 +368,19 @@
 	}
 }
 
-int js_compare(js_State *J)
+int js_compare(js_State *J, int *okay)
 {
 	js_Value va = js_toprimitive(J, -2, JS_HNUMBER);
 	js_Value vb = js_toprimitive(J, -1, JS_HNUMBER);
 
+	*okay = 1;
 	if (va.type == JS_TSTRING && vb.type == JS_TSTRING) {
 		return strcmp(va.u.string, vb.u.string);
 	} else {
 		double x = jsV_tonumber(J, &va);
 		double y = jsV_tonumber(J, &vb);
+		if (isnan(x) || isnan(y))
+			*okay = 0;
 		return x < y ? -1 : x > y ? 1 : 0;
 	}
 }