From 6c27423adc721ddeda87e87892d2aa3bfd6dad68 Mon Sep 17 00:00:00 2001
From: "Rob Swindell (on Windows 11)" <rob@synchro.net>
Date: Thu, 28 Dec 2023 18:08:38 -0800
Subject: [PATCH] Fix misuse of JSVAL_TO_DOUBLE() for "cost" and "size"
 file-meta-obj properties

As pointed out by echicken: when setting the "cost" property to any value, the actual
file's cost would be set to 9223372036854776000 regardless of what number was in the
provided file metadata object. Most jsval numbers aren't doubles (they're ints) so
need to use JS_ValueToNumber() to do the proper conversion, regardless of underlying
type.

Noticed the same problem with the "size" property.

Thanks for the tests and report echicken!
---
 src/sbbs3/js_filebase.c | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/src/sbbs3/js_filebase.c b/src/sbbs3/js_filebase.c
index 631dba480a..fa842a56d2 100644
--- a/src/sbbs3/js_filebase.c
+++ b/src/sbbs3/js_filebase.c
@@ -328,7 +328,9 @@ parse_file_index_properties(JSContext *cx, JSObject* obj, fileidxrec_t* idx)
 		SAFECOPY(idx->name, cp);
 	}
 	if(JS_GetProperty(cx, obj, prop_name = "size", &val) && !JSVAL_NULL_OR_VOID(val)) {
-		smb_setfilesize(&idx->idx, (uint64_t)JSVAL_TO_DOUBLE(val));
+		jsdouble d;
+		if(JS_ValueToNumber(cx, val, &d))
+			smb_setfilesize(&idx->idx, (uint64_t)d);
 	}
 	if(JS_GetProperty(cx, obj, prop_name = "crc16", &val) && !JSVAL_NULL_OR_VOID(val)) {
 		idx->hash.data.crc16 = JSVAL_TO_INT(val);
@@ -571,11 +573,14 @@ parse_file_properties(JSContext *cx, JSObject* obj, file_t* file, char** extdesc
 	}
 	prop_name = "cost";
 	if(JS_GetProperty(cx, obj, prop_name, &val) && !JSVAL_NULL_OR_VOID(val)) {
-		uint64_t cost = (uint64_t)JSVAL_TO_DOUBLE(val);
-		if((file->cost != 0 || cost != 0) && (result = smb_new_hfield(file, SMB_COST, sizeof(cost), &cost)) != SMB_SUCCESS) {
-			free(cp);
-			JS_ReportError(cx, "Error %d adding '%s' property to file object", result, prop_name);
-			return result;
+		jsdouble d;
+		if(JS_ValueToNumber(cx, val, &d)) {
+			uint64_t cost = (uint64_t)d;
+			if((file->cost != 0 || cost != 0) && (result = smb_new_hfield(file, SMB_COST, sizeof(cost), &cost)) != SMB_SUCCESS) {
+				free(cp);
+				JS_ReportError(cx, "Error %d adding '%s' property to file object", result, prop_name);
+				return result;
+			}
 		}
 	}
 	prop_name = "added";
-- 
GitLab