Compare commits

...

1 Commits

Author SHA1 Message Date
Claude Bot
fe99fab134 fix(bindings): add exception scope checks in JSConnectionsList and NodeModuleModule
- Add RETURN_IF_EXCEPTION checks after iterator.next() and putDirectIndex() calls
  in JSConnectionsList::all(), idle(), active(), and expired() methods
- Fix expired() to use iter->next(globalObject, item) pattern instead of iter->next(vm)
- Add proper throw scope handling in getBuiltinModulesObject() and getGlobalPathsObject()
- Replace catch scope with throw scope in generateNativeModule_NodeModule()

This fixes exception scope validation failures when running with
BUN_JSC_validateExceptionChecks=1.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-15 03:09:48 +00:00
2 changed files with 21 additions and 16 deletions

View File

@@ -62,12 +62,14 @@ JSArray* JSConnectionsList::all(JSGlobalObject* globalObject)
JSValue item;
size_t i = 0;
while (iter->next(globalObject, item)) {
RETURN_IF_EXCEPTION(scope, nullptr);
JSHTTPParser* parser = jsDynamicCast<JSHTTPParser*>(item);
if (!parser) {
continue;
}
result->putDirectIndex(globalObject, i++, parser);
RETURN_IF_EXCEPTION(scope, nullptr);
}
return result;
@@ -88,6 +90,7 @@ JSArray* JSConnectionsList::idle(JSGlobalObject* globalObject)
JSValue item;
size_t i = 0;
while (iter->next(globalObject, item)) {
RETURN_IF_EXCEPTION(scope, nullptr);
JSHTTPParser* parser = jsDynamicCast<JSHTTPParser*>(item);
if (!parser) {
continue;
@@ -95,6 +98,7 @@ JSArray* JSConnectionsList::idle(JSGlobalObject* globalObject)
if (parser->impl()->lastMessageStart() == 0) {
result->putDirectIndex(globalObject, i++, parser);
RETURN_IF_EXCEPTION(scope, nullptr);
}
}
@@ -116,12 +120,14 @@ JSArray* JSConnectionsList::active(JSGlobalObject* globalObject)
JSValue item;
size_t i = 0;
while (iter->next(globalObject, item)) {
RETURN_IF_EXCEPTION(scope, nullptr);
JSHTTPParser* parser = jsDynamicCast<JSHTTPParser*>(item);
if (!parser) {
continue;
}
result->putDirectIndex(globalObject, i++, parser);
RETURN_IF_EXCEPTION(scope, nullptr);
}
return result;
@@ -139,18 +145,20 @@ JSArray* JSConnectionsList::expired(JSGlobalObject* globalObject, uint64_t heade
auto iter = JSSetIterator::create(vm, globalObject->setIteratorStructure(), active, IterationKind::Keys);
RETURN_IF_EXCEPTION(scope, nullptr);
JSValue item = iter->next(vm);
JSValue item;
size_t i = 0;
while (!item.isEmpty()) {
while (iter->next(globalObject, item)) {
RETURN_IF_EXCEPTION(scope, nullptr);
JSHTTPParser* parser = jsDynamicCast<JSHTTPParser*>(item);
if (!parser) {
item = iter->next(vm);
continue;
}
if ((!parser->impl()->headersCompleted() && headersDeadline > 0 && parser->impl()->lastMessageStart() < headersDeadline) || (requestDeadline > 0 && parser->impl()->lastMessageStart() < requestDeadline)) {
result->putDirectIndex(globalObject, i++, item);
RETURN_IF_EXCEPTION(scope, nullptr);
active->remove(globalObject, item);
RETURN_IF_EXCEPTION(scope, nullptr);
}
}

View File

@@ -654,6 +654,9 @@ static JSValue getSourceMapFunction(VM& vm, JSObject* moduleObject)
static JSValue getBuiltinModulesObject(VM& vm, JSObject* moduleObject)
{
auto* globalObject = defaultGlobalObject(moduleObject->globalObject());
auto scope = DECLARE_THROW_SCOPE(vm);
MarkedArgumentBuffer args;
args.ensureCapacity(countof(builtinModuleNames));
@@ -661,8 +664,7 @@ static JSValue getBuiltinModulesObject(VM& vm, JSObject* moduleObject)
args.append(JSC::jsOwnedString(vm, String(builtinModuleNames[i])));
}
auto* globalObject = defaultGlobalObject(moduleObject->globalObject());
return JSC::constructArray(globalObject, static_cast<JSC::ArrayAllocationProfile*>(nullptr), JSC::ArgList(args));
RELEASE_AND_RETURN(scope, JSC::constructArray(globalObject, static_cast<JSC::ArrayAllocationProfile*>(nullptr), JSC::ArgList(args)));
}
static JSValue getConstantsObject(VM& vm, JSObject* moduleObject)
@@ -690,9 +692,10 @@ static JSValue getConstantsObject(VM& vm, JSObject* moduleObject)
static JSValue getGlobalPathsObject(VM& vm, JSObject* moduleObject)
{
return JSC::constructEmptyArray(
auto scope = DECLARE_THROW_SCOPE(vm);
RELEASE_AND_RETURN(scope, JSC::constructEmptyArray(
moduleObject->globalObject(),
static_cast<ArrayAllocationProfile*>(nullptr), 0);
static_cast<ArrayAllocationProfile*>(nullptr), 0));
}
JSC_DEFINE_HOST_FUNCTION(jsFunctionSetCJSWrapperItem, (JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
@@ -1150,14 +1153,8 @@ void generateNativeModule_NodeModule(JSC::JSGlobalObject* lexicalGlobalObject,
{
Zig::GlobalObject* globalObject = defaultGlobalObject(lexicalGlobalObject);
auto& vm = JSC::getVM(globalObject);
auto catchScope = DECLARE_CATCH_SCOPE(vm);
auto scope = DECLARE_THROW_SCOPE(vm);
auto* constructor = globalObject->m_nodeModuleConstructor.getInitializedOnMainThread(globalObject);
if (constructor->hasNonReifiedStaticProperties()) {
constructor->reifyAllStaticProperties(globalObject);
if (catchScope.exception()) {
catchScope.clearException();
}
}
exportNames.reserveCapacity(Bun::countof(Bun::nodeModuleObjectTableValues) + 1);
exportValues.ensureCapacity(Bun::countof(Bun::nodeModuleObjectTableValues) + 1);
@@ -1170,9 +1167,9 @@ void generateNativeModule_NodeModule(JSC::JSGlobalObject* lexicalGlobalObject,
const auto& property = Identifier::fromString(vm, entry.m_key);
JSValue value = constructor->get(globalObject, property);
if (catchScope.exception()) [[unlikely]] {
if (scope.exception()) [[unlikely]] {
value = {};
catchScope.clearException();
scope.clearException();
}
exportNames.append(property);