diff options
Diffstat (limited to 'src/mongo/db/storage/key_string.cpp')
-rw-r--r-- | src/mongo/db/storage/key_string.cpp | 92 |
1 files changed, 66 insertions, 26 deletions
diff --git a/src/mongo/db/storage/key_string.cpp b/src/mongo/db/storage/key_string.cpp index 0685576dabc..2e62f8489a5 100644 --- a/src/mongo/db/storage/key_string.cpp +++ b/src/mongo/db/storage/key_string.cpp @@ -250,7 +250,7 @@ T readType(BufReader* reader, bool inverted) { StringData readCString(BufReader* reader) { const char* start = static_cast<const char*>(reader->pos()); const char* end = static_cast<const char*>(memchr(start, 0x0, reader->remaining())); - invariant(end); + uassert(50816, "Failed to find null terminator in string.", end); size_t actualBytes = end - start; reader->skip(1 + actualBytes); return StringData(start, actualBytes); @@ -282,7 +282,7 @@ StringData readCStringWithNuls(BufReader* reader, std::string* scratch) { string readInvertedCString(BufReader* reader) { const char* start = static_cast<const char*>(reader->pos()); const char* end = static_cast<const char*>(memchr(start, 0xFF, reader->remaining())); - invariant(end); + uassert(50817, "Failed to find '0xFF' in inverted string.", end); size_t actualBytes = end - start; string s(start, actualBytes); for (size_t i = 0; i < s.size(); i++) { @@ -307,7 +307,7 @@ string readInvertedCStringWithNuls(BufReader* reader) { const char* start = static_cast<const char*>(reader->pos()); const char* end = static_cast<const char*>(memchr(start, 0xFF, reader->remaining())); - invariant(end); + uassert(50820, "Failed to find '0xFF' in inverted string.", end); size_t actualBytes = end - start; out.append(start, actualBytes); @@ -1122,7 +1122,9 @@ Decimal128 readDecimalContinuation(BufReader* reader, bool inverted, Decimal128 uint64_t continuation = endian::bigToNative(readType<uint64_t>(reader, inverted)); num = num.normalize(); num = num.add(Decimal128(num.isNegative(), num.getBiasedExponent(), 0, continuation), &flags); - invariant(!(Decimal128::hasFlag(flags, Decimal128::kInexact))); + uassert(50815, + "Unexpected inexact flag set after Decimal addition.", + !(Decimal128::hasFlag(flags, Decimal128::kInexact))); return num; } @@ -1182,7 +1184,9 @@ void toBsonValue(uint8_t ctype, if (originalType == TypeBits::kString) { *stream << readInvertedCStringWithNuls(reader); } else { - dassert(originalType == TypeBits::kSymbol); + uassert(50827, + "Expected original type to be Symbol.", + originalType == TypeBits::kSymbol); *stream << BSONSymbol(readInvertedCStringWithNuls(reader)); } @@ -1191,7 +1195,9 @@ void toBsonValue(uint8_t ctype, if (originalType == TypeBits::kString) { *stream << readCStringWithNuls(reader, &scratch); } else { - dassert(originalType == TypeBits::kSymbol); + uassert(50828, + "Expected original type to be Symbol.", + originalType == TypeBits::kSymbol); *stream << BSONSymbol(readCStringWithNuls(reader, &scratch)); } } @@ -1302,7 +1308,9 @@ void toBsonValue(uint8_t ctype, if (type == TypeBits::kDouble) { *stream << std::numeric_limits<double>::quiet_NaN(); } else { - invariant(type == TypeBits::kDecimal && version == KeyString::Version::V1); + uassert(50819, + "Invalid type bits for numeric NaN", + type == TypeBits::kDecimal && version == KeyString::Version::V1); *stream << Decimal128::kPositiveNaN; } break; @@ -1361,7 +1369,9 @@ void toBsonValue(uint8_t ctype, bin = isNegative ? -std::numeric_limits<double>::infinity() : std::numeric_limits<double>::infinity(); } else { // Huge decimal number, directly output - invariant(originalType == TypeBits::kDecimal); + uassert(50818, + "Invalid type bits for decimal number.", + originalType == TypeBits::kDecimal); uint64_t highbits = encoded & ~(1ULL << 63); uint64_t lowbits = endian::bigToNative(readType<uint64_t>(reader, inverted)); Decimal128 dec(Decimal128::Value{lowbits, highbits}); @@ -1378,10 +1388,14 @@ void toBsonValue(uint8_t ctype, *stream << bin; } else if (originalType == TypeBits::kLong) { // This can only happen for a single number. - invariant(bin == static_cast<double>(std::numeric_limits<long long>::min())); + uassert(50821, + "Unexpected value for large number.", + bin == static_cast<double>(std::numeric_limits<long long>::min())); *stream << std::numeric_limits<long long>::min(); } else { - invariant(originalType == TypeBits::kDecimal && version != KeyString::Version::V0); + uassert(50826, + "Unexpected type of large number.", + originalType == TypeBits::kDecimal && version != KeyString::Version::V0); const auto roundAwayFromZero = isNegative ? Decimal128::kRoundTowardNegative : Decimal128::kRoundTowardPositive; Decimal128 dec(bin, Decimal128::kRoundTo34Digits, roundAwayFromZero); @@ -1406,7 +1420,9 @@ void toBsonValue(uint8_t ctype, if (version == KeyString::Version::V0) { // for these, the raw double was stored intact, including sign bit. - invariant(originalType == TypeBits::kDouble); + uassert(50812, + "Invalid type bits for small number.", + originalType == TypeBits::kDouble); double d; memcpy(&d, &encoded, sizeof(d)); *stream << d; @@ -1438,12 +1454,14 @@ void toBsonValue(uint8_t ctype, double scaledBin; memcpy(&scaledBin, &encoded, sizeof(scaledBin)); if (originalType == TypeBits::kDouble) { - invariant(!hasDecimalContinuation); + uassert(50822, "Unexpected decimal continuation.", !hasDecimalContinuation); double bin = scaledBin * kTinyDoubleExponentDownshiftFactor; *stream << (isNegative ? -bin : bin); break; } - invariant(originalType == TypeBits::kDecimal && hasDecimalContinuation); + uassert(50823, + "Expected decimal continuation.", + originalType == TypeBits::kDecimal && hasDecimalContinuation); // If the actual double would be subnormal, scale in decimal domain. Decimal128 dec; @@ -1474,13 +1492,17 @@ void toBsonValue(uint8_t ctype, double bin; memcpy(&bin, &encoded, sizeof(bin)); if (originalType == TypeBits::kDouble) { - invariant(dcm == KeyString::kDCMEqualToDouble); + uassert(50824, + "Decimal contuation mismatch.", + dcm == KeyString::kDCMEqualToDouble); *stream << (isNegative ? -bin : bin); break; } // Deal with decimal cases - invariant(originalType == TypeBits::kDecimal); + uassert(50825, + "Unexpected type for small number, expected decimal.", + originalType == TypeBits::kDecimal); Decimal128 dec; switch (dcm) { case KeyString::kDCMEqualToDoubleRoundedUpTo15Digits: @@ -1562,14 +1584,16 @@ void toBsonValue(uint8_t ctype, *stream << adjustDecimalExponent(typeBits, Decimal128(integerPart)); break; default: - MONGO_UNREACHABLE; + uasserted(50831, "Unexpected type for positive int."); } break; } // KeyString V0: anything fractional is a double if (version == KeyString::Version::V0) { - invariant(originalType == TypeBits::kDouble); + uassert(50832, + "Expected type double for fractional part.", + originalType == TypeBits::kDouble); const uint64_t exponent = (64 - countLeadingZeros64(integerPart)) - 1; const size_t fractionalBits = (52 - exponent); const size_t fractionalBytes = (fractionalBits + 7) / 8; @@ -1614,7 +1638,7 @@ void toBsonValue(uint8_t ctype, : KeyString::kDCMHasContinuationLargerThanDoubleRoundedUpTo15Digits; // Deal with decimal cases - invariant(originalType == TypeBits::kDecimal); + uassert(50810, "Expected type Decimal.", originalType == TypeBits::kDecimal); Decimal128 dec; switch (dcm) { case KeyString::kDCMEqualToDoubleRoundedUpTo15Digits: @@ -1637,7 +1661,7 @@ void toBsonValue(uint8_t ctype, break; } default: - MONGO_UNREACHABLE; + uasserted(50811, str::stream() << "Unknown type: " << ctype); } } @@ -1936,7 +1960,7 @@ Decimal128 adjustDecimalExponent(TypeBits::Reader* typeBits, Decimal128 num) { // possible, we must be able to scale up. Scaling always must be exact and not change the value. const uint32_t kMaxExpAdjust = 33; const uint32_t kMaxExpIncrementForZeroHighCoefficient = 19; - dassert(!num.isZero()); + uassert(50829, "Expected non-zero number for decimal.", !num.isZero()); const uint32_t origExp = num.getBiasedExponent(); const uint8_t storedBits = typeBits->readDecimalExponent(); @@ -1958,16 +1982,22 @@ Decimal128 adjustDecimalExponent(TypeBits::Reader* typeBits, Decimal128 num) { // Increase exponent and decrease (right shift) coefficient. uint32_t flags = Decimal128::SignalingFlag::kNoFlag; auto quantized = num.quantize(Decimal128(0, highExp, 0, 1), &flags); - invariant(flags == Decimal128::SignalingFlag::kNoFlag); // must be exact + uassert(50813, + "Unexpected signaling flag for Decimal quantization.", + flags == Decimal128::SignalingFlag::kNoFlag); // must be exact num = quantized; } else { // Decrease exponent and increase (left shift) coefficient. uint32_t lowExp = highExp - (1U << KeyString::TypeBits::kStoredDecimalExponentBits); - invariant(lowExp >= origExp - kMaxExpAdjust); + uassert(50814, + "Unexpected exponent values after adjusting Decimal.", + lowExp >= origExp - kMaxExpAdjust); num = num.add(Decimal128(0, lowExp, 0, 0)); } - dassert((num.getBiasedExponent() & KeyString::TypeBits::kStoredDecimalExponentMask) == - (highExp & KeyString::TypeBits::kStoredDecimalExponentMask)); + uassert(50830, + "Unexpected biased exponent in decimal.", + (num.getBiasedExponent() & KeyString::TypeBits::kStoredDecimalExponentMask) == + (highExp & KeyString::TypeBits::kStoredDecimalExponentMask)); return num; } @@ -1996,7 +2026,10 @@ size_t KeyString::getKeySize(const char* buffer, return (len - (remainingBytes + 1)); } -BSONObj KeyString::toBson(const char* buffer, size_t len, Ordering ord, const TypeBits& typeBits) { +BSONObj KeyString::toBsonSafe(const char* buffer, + size_t len, + Ordering ord, + const TypeBits& typeBits) { BSONObjBuilder builder; BufReader reader(buffer, len); TypeBits::Reader typeBitsReader(typeBits); @@ -2018,6 +2051,13 @@ BSONObj KeyString::toBson(const char* buffer, size_t len, Ordering ord, const Ty return builder.obj(); } +BSONObj KeyString::toBson(const char* buffer, + size_t len, + Ordering ord, + const TypeBits& typeBits) noexcept { + return toBsonSafe(buffer, len, ord, typeBits); +} + BSONObj KeyString::toBson(StringData data, Ordering ord, const TypeBits& typeBits) { return toBson(data.rawData(), data.size(), ord, typeBits); } @@ -2180,7 +2220,7 @@ uint8_t KeyString::TypeBits::Reader::readBit() { const uint8_t offsetInByte = _curBit % 8; _curBit++; - dassert(byte <= _typeBits.getSizeByte()); + uassert(50615, "Invalid size byte.", byte <= _typeBits.getSizeByte()); return (_typeBits._buf[byte] & (1 << offsetInByte)) ? 1 : 0; } |