From fb6b4df1ef9718d1c5d5b44979ba46deeaf977b3 Mon Sep 17 00:00:00 2001 From: Nik Pavlov Date: Fri, 12 Apr 2024 15:37:33 +0000 Subject: [PATCH] Fix how CefV8ValueImpl differentiates INT and UINT types (fixes #3657) --- libcef/renderer/v8_impl.cc | 18 ++++++++--- tests/ceftests/v8_unittest.cc | 57 +++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 4 deletions(-) diff --git a/libcef/renderer/v8_impl.cc b/libcef/renderer/v8_impl.cc index a7e232448..be981daef 100644 --- a/libcef/renderer/v8_impl.cc +++ b/libcef/renderer/v8_impl.cc @@ -6,6 +6,7 @@ // Otherwise there will be compile errors in wtf/MathExtras.h. #define _USE_MATH_DEFINES +#include #include #include #include @@ -49,6 +50,8 @@ namespace { static const char kCefTrackObject[] = "Cef::TrackObject"; +constexpr int32_t kMaxInt32 = std::numeric_limits::max(); +constexpr uint32_t kMaxInt32AsUint32 = static_cast(kMaxInt32); void MessageListenerCallbackImpl(v8::Handle message, v8::Handle data); @@ -1693,12 +1696,13 @@ bool CefV8ValueImpl::IsBool() { bool CefV8ValueImpl::IsInt() { CEF_V8_REQUIRE_ISOLATE_RETURN(false); - return (type_ == TYPE_INT || type_ == TYPE_UINT); + return type_ == TYPE_INT || + (type_ == TYPE_UINT && uint_value_ <= kMaxInt32AsUint32); } bool CefV8ValueImpl::IsUInt() { CEF_V8_REQUIRE_ISOLATE_RETURN(false); - return (type_ == TYPE_INT || type_ == TYPE_UINT); + return type_ == TYPE_UINT || (type_ == TYPE_INT && int_value_ >= 0); } bool CefV8ValueImpl::IsDouble() { @@ -1807,17 +1811,23 @@ bool CefV8ValueImpl::GetBoolValue() { int32_t CefV8ValueImpl::GetIntValue() { CEF_V8_REQUIRE_ISOLATE_RETURN(0); - if (type_ == TYPE_INT || type_ == TYPE_UINT) { + if (type_ == TYPE_INT) { return int_value_; } + if (type_ == TYPE_UINT && uint_value_ <= kMaxInt32AsUint32) { + return static_cast(uint_value_); + } return 0; } uint32_t CefV8ValueImpl::GetUIntValue() { CEF_V8_REQUIRE_ISOLATE_RETURN(0); - if (type_ == TYPE_INT || type_ == TYPE_UINT) { + if (type_ == TYPE_UINT) { return uint_value_; } + if (type_ == TYPE_INT && int_value_ >= 0) { + return static_cast(int_value_); + } return 0; } diff --git a/tests/ceftests/v8_unittest.cc b/tests/ceftests/v8_unittest.cc index ec13d2968..febf8c311 100644 --- a/tests/ceftests/v8_unittest.cc +++ b/tests/ceftests/v8_unittest.cc @@ -49,7 +49,9 @@ enum V8TestMode { V8TEST_NULL_CREATE, V8TEST_BOOL_CREATE, V8TEST_INT_CREATE, + V8TEST_NEGATIVE_INT_CREATE, V8TEST_UINT_CREATE, + V8TEST_BIG_UINT_CREATE, V8TEST_DOUBLE_CREATE, V8TEST_DATE_CREATE, V8TEST_STRING_CREATE, @@ -120,9 +122,15 @@ class V8RendererTest : public ClientAppRenderer::Delegate, case V8TEST_INT_CREATE: RunIntCreateTest(); break; + case V8TEST_NEGATIVE_INT_CREATE: + RunNegativeIntCreateTest(); + break; case V8TEST_UINT_CREATE: RunUIntCreateTest(); break; + case V8TEST_BIG_UINT_CREATE: + RunBigUIntCreateTest(); + break; case V8TEST_DOUBLE_CREATE: RunDoubleCreateTest(); break; @@ -349,6 +357,29 @@ class V8RendererTest : public ClientAppRenderer::Delegate, DestroyTest(); } + void RunNegativeIntCreateTest() { + CefRefPtr value = CefV8Value::CreateInt(-12); + EXPECT_TRUE(value.get()); + EXPECT_TRUE(value->IsInt()); + EXPECT_TRUE(value->IsDouble()); + EXPECT_EQ(-12, value->GetIntValue()); + EXPECT_EQ(-12, value->GetDoubleValue()); + EXPECT_EQ(0u, value->GetUIntValue()); + + EXPECT_FALSE(value->IsUInt()); + EXPECT_FALSE(value->IsUndefined()); + EXPECT_FALSE(value->IsArray()); + EXPECT_FALSE(value->IsBool()); + EXPECT_FALSE(value->IsDate()); + EXPECT_FALSE(value->IsFunction()); + EXPECT_FALSE(value->IsNull()); + EXPECT_FALSE(value->IsObject()); + EXPECT_FALSE(value->IsPromise()); + EXPECT_FALSE(value->IsString()); + + DestroyTest(); + } + void RunUIntCreateTest() { CefRefPtr value = CefV8Value::CreateUInt(12); EXPECT_TRUE(value.get()); @@ -372,6 +403,30 @@ class V8RendererTest : public ClientAppRenderer::Delegate, DestroyTest(); } + void RunBigUIntCreateTest() { + uint32_t big_value = 2147483648u; + CefRefPtr value = CefV8Value::CreateUInt(big_value); + EXPECT_TRUE(value.get()); + EXPECT_TRUE(value->IsUInt()); + EXPECT_TRUE(value->IsDouble()); + EXPECT_EQ(big_value, value->GetUIntValue()); + EXPECT_EQ(big_value, value->GetDoubleValue()); + EXPECT_EQ(0, value->GetIntValue()); + + EXPECT_FALSE(value->IsInt()); + EXPECT_FALSE(value->IsUndefined()); + EXPECT_FALSE(value->IsArray()); + EXPECT_FALSE(value->IsBool()); + EXPECT_FALSE(value->IsDate()); + EXPECT_FALSE(value->IsFunction()); + EXPECT_FALSE(value->IsNull()); + EXPECT_FALSE(value->IsObject()); + EXPECT_FALSE(value->IsPromise()); + EXPECT_FALSE(value->IsString()); + + DestroyTest(); + } + void RunDoubleCreateTest() { CefRefPtr value = CefV8Value::CreateDouble(12.1223); EXPECT_TRUE(value.get()); @@ -3355,7 +3410,9 @@ void CreateV8RendererTests(ClientAppRenderer::DelegateSet& delegates) { V8_TEST(NullCreate, V8TEST_NULL_CREATE) V8_TEST(BoolCreate, V8TEST_BOOL_CREATE) V8_TEST(IntCreate, V8TEST_INT_CREATE) +V8_TEST(NegativeIntCreate, V8TEST_NEGATIVE_INT_CREATE) V8_TEST(UIntCreate, V8TEST_UINT_CREATE) +V8_TEST(BigUIntCreate, V8TEST_BIG_UINT_CREATE) V8_TEST(DoubleCreate, V8TEST_DOUBLE_CREATE) V8_TEST(DateCreate, V8TEST_DATE_CREATE) V8_TEST(StringCreate, V8TEST_STRING_CREATE)