mirror of
https://github.com/oven-sh/bun
synced 2026-02-28 20:40:59 +01:00
The C++ implementation had two compounding bugs: 1. Parameter names were swapped: Zig passes (min, max) but C++ declared (max, min) 2. The logic used OR short-circuit instead of AND, returning true on the first check Combined, this caused the function to return true when the BigInt was OUTSIDE the range, and false when it was INSIDE — the exact opposite of the intended behavior. Impact: - All BigInt parameter binding in Bun.SQL (MySQL) would fail with ERR_OUT_OF_RANGE for valid in-range values - Out-of-range BigInts would be silently accepted and truncated Fix: Change parameter order to (min, max) and use proper AND logic (return false if < min, otherwise check <= max). Added regression tests via bun:internal-for-testing that directly exercise both functions, plus MySQL integration tests for BigInt parameter binding.
77 lines
2.6 KiB
C++
77 lines
2.6 KiB
C++
#include "root.h"
|
|
|
|
#include "ZigGlobalObject.h"
|
|
#include "JavaScriptCore/JSCJSValue.h"
|
|
#include "JavaScriptCore/JSCast.h"
|
|
#include "JavaScriptCore/JSArrayBufferView.h"
|
|
|
|
#if ASAN_ENABLED
|
|
#include <sanitizer/lsan_interface.h>
|
|
#endif
|
|
|
|
namespace Bun {
|
|
|
|
using namespace JSC;
|
|
|
|
JSC_DEFINE_HOST_FUNCTION(jsFunction_arrayBufferViewHasBuffer, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
|
|
{
|
|
auto value = callFrame->argument(0);
|
|
auto view = jsCast<WebCore::JSArrayBufferView*>(value);
|
|
return JSValue::encode(jsBoolean(view->hasArrayBuffer()));
|
|
}
|
|
|
|
JSC_DEFINE_HOST_FUNCTION(jsFunction_hasReifiedStatic, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
|
|
{
|
|
auto object = callFrame->argument(0).getObject();
|
|
if (!object) {
|
|
return JSValue::encode(jsBoolean(false));
|
|
}
|
|
|
|
if (object->hasNonReifiedStaticProperties()) {
|
|
return JSValue::encode(jsBoolean(true));
|
|
}
|
|
|
|
return JSValue::encode(jsBoolean(false));
|
|
}
|
|
|
|
JSC_DEFINE_HOST_FUNCTION(jsFunction_lsanDoLeakCheck, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
|
|
{
|
|
#if ASAN_ENABLED
|
|
return JSValue::encode(jsNumber(__lsan_do_recoverable_leak_check()));
|
|
#endif
|
|
return encodedJSUndefined();
|
|
}
|
|
|
|
extern "C" bool JSC__isBigIntInInt64Range(JSC::EncodedJSValue value, int64_t min, int64_t max);
|
|
extern "C" bool JSC__isBigIntInUInt64Range(JSC::EncodedJSValue value, uint64_t min, uint64_t max);
|
|
|
|
// For testing JSC__isBigIntInInt64Range / JSC__isBigIntInUInt64Range from JS.
|
|
// args: (bigint, min: number|bigint, max: number|bigint, unsigned: boolean)
|
|
JSC_DEFINE_HOST_FUNCTION(jsFunction_isBigIntInRange, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
|
|
{
|
|
auto& vm = globalObject->vm();
|
|
auto scope = DECLARE_THROW_SCOPE(vm);
|
|
|
|
JSValue value = callFrame->argument(0);
|
|
JSValue minArg = callFrame->argument(1);
|
|
JSValue maxArg = callFrame->argument(2);
|
|
bool isUnsigned = callFrame->argument(3).toBoolean(globalObject);
|
|
RETURN_IF_EXCEPTION(scope, {});
|
|
|
|
if (isUnsigned) {
|
|
uint64_t min = minArg.toBigUInt64(globalObject);
|
|
RETURN_IF_EXCEPTION(scope, {});
|
|
uint64_t max = maxArg.toBigUInt64(globalObject);
|
|
RETURN_IF_EXCEPTION(scope, {});
|
|
return JSValue::encode(jsBoolean(JSC__isBigIntInUInt64Range(JSValue::encode(value), min, max)));
|
|
}
|
|
|
|
int64_t min = minArg.toBigInt64(globalObject);
|
|
RETURN_IF_EXCEPTION(scope, {});
|
|
int64_t max = maxArg.toBigInt64(globalObject);
|
|
RETURN_IF_EXCEPTION(scope, {});
|
|
return JSValue::encode(jsBoolean(JSC__isBigIntInInt64Range(JSValue::encode(value), min, max)));
|
|
}
|
|
|
|
}
|