From 22f888c1b065e84e25b26bd729c8f00545238fce Mon Sep 17 00:00:00 2001 From: Suyog241005 Date: Wed, 3 Jun 2026 21:27:57 +0530 Subject: [PATCH] fix: correct non-transitive keywordComparator in validation.js MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous comparator always returned -1 or 1, never 0. This violates the mathematical contract that Array.prototype.sort() requires: compare(a, a) must return 0 (reflexivity) When two non-last-keywords are compared against each other, the old comparator returned 1 (meaning 'a > b'), which is incorrect—they are equal in priority. V8's Timsort can produce non-deterministic or incorrect orderings when comparators break this contract. Replace it with a correct, stable comparator that returns 0 for two elements that have the same 'lastness', 1 if only a is a last-keyword, and -1 if only b is a last-keyword. --- lib/keywords/validation.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/keywords/validation.js b/lib/keywords/validation.js index dcd148ab..06f34e8d 100644 --- a/lib/keywords/validation.js +++ b/lib/keywords/validation.js @@ -56,7 +56,7 @@ const lastKeywords = new Set([ "https://json-schema.org/keyword/unevaluatedProperties", "https://json-schema.org/keyword/unevaluatedItems" ]); -const keywordComparator = (_a, b) => lastKeywords.has(b[0]) ? -1 : 1; +const keywordComparator = (a, b) => lastKeywords.has(a[0]) - lastKeywords.has(b[0]); const interpret = (url, instance, context) => { let valid = true;