github-actions[bot] commented on code in PR #63396:
URL: https://github.com/apache/doris/pull/63396#discussion_r3273249862


##########
be/src/util/jsonb_document.h:
##########
@@ -1004,6 +1007,184 @@ struct ArrayVal : public ContainerVal {
 
 namespace jsonb_detail {
 
+struct JsonbScaledDecimal {
+    wide::Int256 value;
+    uint32_t scale;
+};
+
+inline bool is_numeric(const JsonbValue* value) {
+    return value->isInt() || value->isDouble() || value->isFloat() || 
value->isDecimal();
+}
+
+inline double floating_value(const JsonbValue* value) {
+    if (value->isDouble()) {
+        return value->unpack<JsonbDoubleVal>()->val();
+    }
+    return value->unpack<JsonbFloatVal>()->val();
+}
+
+inline JsonbScaledDecimal get_scaled_decimal(const JsonbValue* value) {
+    switch (value->type) {
+    case JsonbType::T_Decimal32: {
+        const auto* decimal = value->unpack<JsonbDecimal32>();
+        return {wide::Int256(decimal->val()), decimal->scale};
+    }
+    case JsonbType::T_Decimal64: {
+        const auto* decimal = value->unpack<JsonbDecimal64>();
+        return {wide::Int256(decimal->val()), decimal->scale};
+    }
+    case JsonbType::T_Decimal128: {
+        const auto* decimal = value->unpack<JsonbDecimal128>();
+        return {wide::Int256(decimal->val()), decimal->scale};
+    }
+    case JsonbType::T_Decimal256: {
+        const auto* decimal = value->unpack<JsonbDecimal256>();
+        return {decimal->val(), decimal->scale};
+    }
+    default:
+        throw Exception(ErrorCode::INTERNAL_ERROR, "Invalid JSONB decimal 
value type: {}",
+                        static_cast<int32_t>(value->type));
+    }
+}
+
+inline bool scaled_decimal_equal_decimal(const JsonbScaledDecimal& lhs,
+                                         const JsonbScaledDecimal& rhs) {
+    if (lhs.scale == rhs.scale) {
+        return lhs.value == rhs.value;
+    }
+
+    if (lhs.scale < rhs.scale) {
+        const auto scale_multiplier = 
decimal_scale_multiplier<wide::Int256>(rhs.scale - lhs.scale);
+        return rhs.value % scale_multiplier == 0 && lhs.value == rhs.value / 
scale_multiplier;
+    }
+
+    const auto scale_multiplier = 
decimal_scale_multiplier<wide::Int256>(lhs.scale - rhs.scale);
+    return lhs.value % scale_multiplier == 0 && lhs.value / scale_multiplier 
== rhs.value;
+}
+
+inline bool scaled_decimal_equal_integer(const JsonbScaledDecimal& decimal, 
int128_t integer) {
+    const auto integer_value = wide::Int256(integer);
+    if (decimal.scale == 0) {
+        return decimal.value == integer_value;
+    }
+
+    const auto scale_multiplier = 
decimal_scale_multiplier<wide::Int256>(decimal.scale);
+    return decimal.value % scale_multiplier == 0 &&
+           decimal.value / scale_multiplier == integer_value;
+}
+
+inline constexpr auto kPowersOfFive = [] {
+    std::array<wide::Int256, BeConsts::MAX_DECIMALV3_SCALE + 1> powers {};
+    powers[0] = 1;
+    for (size_t i = 1; i < powers.size(); ++i) {
+        powers[i] = powers[i - 1] * 5;
+    }
+    return powers;
+}();
+
+inline wide::Int256 power_of_five(uint32_t exponent) {

Review Comment:
   `decimal.scale` comes directly from the serialized JSONB decimal metadata, 
but this helper only has a `DCHECK_LE` before indexing `kPowersOfFive`. In 
release builds the check is compiled out, and neither 
`JsonbWriter::writeDecimal` nor `JsonbDocument::createValue` validates that the 
stored scale is <= `BeConsts::MAX_DECIMALV3_SCALE`. A malformed or incompatible 
JSONB decimal compared with a float/double can therefore call 
`power_of_five(decimal.scale)` and read past this table. Please validate the 
scale on the release path before indexing, or return/throw an error for invalid 
decimal metadata.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to