|
|
@@ -557,6 +557,23 @@ Insert after the closing `}, "pick", 2));` at line 1550, before the `// utils.om
|
|
|
return JS_DupValue(ctx, argv[0]);
|
|
|
}
|
|
|
|
|
|
+ // An array index has to fit a uint32_t. A longer run of digits is not a
|
|
|
+ // valid index, and std::stoll would throw std::out_of_range on it - a
|
|
|
+ // C++ exception unwinding through QuickJS C frames takes the runner
|
|
|
+ // process with it, so the parse is bounded rather than guarded after
|
|
|
+ // the fact.
|
|
|
+ auto parseIndex = [](const std::string& text, uint32_t& out) -> bool {
|
|
|
+ if (text.empty() || text.size() > 10) return false;
|
|
|
+ if (text.find_first_not_of("0123456789") != std::string::npos) return false;
|
|
|
+ uint64_t value = 0;
|
|
|
+ for (char c : text) {
|
|
|
+ value = value * 10 + (uint64_t)(c - '0');
|
|
|
+ }
|
|
|
+ if (value > 0xFFFFFFFFull) return false;
|
|
|
+ out = (uint32_t)value;
|
|
|
+ return true;
|
|
|
+ };
|
|
|
+
|
|
|
std::vector<std::string> keys;
|
|
|
size_t start = 0;
|
|
|
while (true) {
|
|
|
@@ -589,22 +606,20 @@ Insert after the closing `}, "pick", 2));` at line 1550, before the `// utils.om
|
|
|
// key[3] - step into the property, then index it
|
|
|
std::string key = raw_key;
|
|
|
bool has_index = false;
|
|
|
- int64_t index = 0;
|
|
|
+ uint32_t index = 0;
|
|
|
size_t bracket = raw_key.find('[');
|
|
|
if (bracket != std::string::npos && raw_key.back() == ']') {
|
|
|
std::string index_text = raw_key.substr(bracket + 1, raw_key.size() - bracket - 2);
|
|
|
- if (!index_text.empty() &&
|
|
|
- index_text.find_first_not_of("0123456789") == std::string::npos) {
|
|
|
+ if (parseIndex(index_text, index)) {
|
|
|
key = raw_key.substr(0, bracket);
|
|
|
- index = std::stoll(index_text);
|
|
|
has_index = true;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (!key.empty()) {
|
|
|
- bool numeric = key.find_first_not_of("0123456789") == std::string::npos;
|
|
|
- if (numeric && is_array) {
|
|
|
- JSValue element = JS_GetPropertyUint32(ctx, current, (uint32_t)std::stoll(key));
|
|
|
+ uint32_t bare_index = 0;
|
|
|
+ if (is_array && parseIndex(key, bare_index)) {
|
|
|
+ JSValue element = JS_GetPropertyUint32(ctx, current, bare_index);
|
|
|
JS_FreeValue(ctx, current);
|
|
|
current = element;
|
|
|
} else {
|
|
|
@@ -623,7 +638,7 @@ Insert after the closing `}, "pick", 2));` at line 1550, before the `// utils.om
|
|
|
JS_FreeValue(ctx, current);
|
|
|
return JS_UNDEFINED;
|
|
|
}
|
|
|
- JSValue element = JS_GetPropertyUint32(ctx, current, (uint32_t)index);
|
|
|
+ JSValue element = JS_GetPropertyUint32(ctx, current, index);
|
|
|
JS_FreeValue(ctx, current);
|
|
|
current = element;
|
|
|
}
|