diff options
author | Alexander Smirnov <alex@ydb.tech> | 2025-03-28 00:51:44 +0000 |
---|---|---|
committer | Alexander Smirnov <alex@ydb.tech> | 2025-03-28 00:51:44 +0000 |
commit | 149dc5893b4b90db5ad40d019d2d1ffa6e1f0abd (patch) | |
tree | 6e3243c1b457c31839ddc9fa75b5f46bcc1fecb4 /library/cpp | |
parent | 4c8dfa633cab20dabf3d11464d986335519bfcfa (diff) | |
parent | 71e9df83f284bf42c2f8ea872752bf02e1055555 (diff) | |
download | ydb-149dc5893b4b90db5ad40d019d2d1ffa6e1f0abd.tar.gz |
Merge branch 'rightlib' into merge-libs-250328-0050
Diffstat (limited to 'library/cpp')
-rw-r--r-- | library/cpp/neh/tcp2.cpp | 30 | ||||
-rw-r--r-- | library/cpp/type_info/type_io.cpp | 33 | ||||
-rw-r--r-- | library/cpp/type_info/ut/type_deserialize.cpp | 34 |
3 files changed, 71 insertions, 26 deletions
diff --git a/library/cpp/neh/tcp2.cpp b/library/cpp/neh/tcp2.cpp index 641408973d..fa24635e46 100644 --- a/library/cpp/neh/tcp2.cpp +++ b/library/cpp/neh/tcp2.cpp @@ -621,8 +621,8 @@ namespace { , State_(Init) , BuffSize_(TTcp2Options::InputBufferSize) , Buff_(new char[BuffSize_]) - , NeedCheckReqsQueue_(0) - , NeedCheckCancelsQueue_(0) + , NeedCheckReqsQueue_(false) + , NeedCheckCancelsQueue_(false) , GenReqId_(0) , LastSendedReqId_(0) { @@ -651,7 +651,7 @@ namespace { throw; } - AtomicSet(NeedCheckReqsQueue_, 1); + NeedCheckReqsQueue_.store(true); req->SetConnection(this); TAtomicBase state = AtomicGet(State_); if (Y_LIKELY(state == Connected)) { @@ -682,7 +682,7 @@ namespace { //called from client thread void Cancel(TRequestId id) { Cancels_.Enqueue(id); - AtomicSet(NeedCheckCancelsQueue_, 1); + NeedCheckCancelsQueue_.store(true); if (Y_LIKELY(AtomicGet(State_) == Connected)) { ProcessOutputCancelsQueue(); } @@ -758,7 +758,7 @@ namespace { do { if (asioThread) { - AtomicSet(NeedCheckCancelsQueue_, 0); + NeedCheckCancelsQueue_.store(false); TRequestId reqId; ProcessReqsInFlyQueue(); @@ -776,14 +776,14 @@ namespace { } } } - } else if (AtomicGet(NeedCheckCancelsQueue_)) { + } else if (NeedCheckCancelsQueue_.load()) { AS_.GetIOService().Post(std::bind(&TConnection::SendMessages, TConnectionRef(this), true)); return; } TRequestId lastReqId = 0; { - AtomicSet(NeedCheckReqsQueue_, 0); + NeedCheckReqsQueue_.store(false); TRequest* reqPtr; while (Reqs_.Dequeue(&reqPtr)) { @@ -824,7 +824,7 @@ namespace { OutputLock_.Release(); - if (!AtomicGet(NeedCheckReqsQueue_) && !AtomicGet(NeedCheckCancelsQueue_)) { + if (!NeedCheckReqsQueue_.load() && !NeedCheckCancelsQueue_.load()) { DBGOUT("TClient::SendMessages(exit2)"); return; } @@ -1031,9 +1031,9 @@ namespace { //output TSpinLock OutputLock_; //protect socket/buffers from simultaneous access from few threads - TAtomic NeedCheckReqsQueue_; + std::atomic<bool> NeedCheckReqsQueue_; TLockFreeQueue<TRequest*> Reqs_; - TAtomic NeedCheckCancelsQueue_; + std::atomic<bool> NeedCheckCancelsQueue_; TLockFreeQueue<TRequestId> Cancels_; TAdaptiveLock GenReqIdLock_; std::atomic<TRequestId> GenReqId_; @@ -1182,7 +1182,7 @@ namespace { , RemoteHost_(NNeh::PrintHostByRfc(*AS_->RemoteEndpoint().Addr())) , BuffSize_(TTcp2Options::InputBufferSize) , Buff_(new char[BuffSize_]) - , NeedCheckOutputQueue_(0) + , NeedCheckOutputQueue_(false) { DBGOUT("TServer::TConnection()"); } @@ -1383,7 +1383,7 @@ namespace { } void ProcessOutputQueue() { - AtomicSet(NeedCheckOutputQueue_, 1); + NeedCheckOutputQueue_.store(true); if (OutputLock_.TryAcquire()) { SendMessages(false); return; @@ -1396,7 +1396,7 @@ namespace { DBGOUT("TServer::SendMessages(enter)"); try { do { - AtomicUnlock(&NeedCheckOutputQueue_); + NeedCheckOutputQueue_.store(false); TAutoPtr<TOutputData> d; while (OutputData_.Dequeue(&d)) { d->MoveTo(OutputBuffers_); @@ -1415,7 +1415,7 @@ namespace { OutputLock_.Release(); - if (!AtomicGet(NeedCheckOutputQueue_)) { + if (!NeedCheckOutputQueue_.load()) { DBGOUT("Server::SendMessages(exit2): " << (int)!OutputLock_.IsLocked()); return; } @@ -1491,7 +1491,7 @@ namespace { //output TSpinLock OutputLock_; //protect socket/buffers from simultaneous access from few threads - TAtomic NeedCheckOutputQueue_; + std::atomic<bool> NeedCheckOutputQueue_; NNeh::TAutoLockFreeQueue<TOutputData> OutputData_; TOutputBuffers OutputBuffers_; }; diff --git a/library/cpp/type_info/type_io.cpp b/library/cpp/type_info/type_io.cpp index 12f0058fed..f397466abc 100644 --- a/library/cpp/type_info/type_io.cpp +++ b/library/cpp/type_info/type_io.cpp @@ -13,6 +13,8 @@ #include <util/generic/vector.h> #include <util/generic/scope.h> +#include <optional> + namespace NTi::NIo { namespace { class TYsonDeserializer: private TNonCopyable { @@ -61,7 +63,8 @@ namespace NTi::NIo { const TType *Key, *Value; }; struct TDecimalData { - ui8 Precision, Scale; + std::optional<ui8> Precision; + std::optional<ui8> Scale; }; using TTypeData = std::variant< std::monostate, @@ -162,11 +165,19 @@ namespace NTi::NIo { } } else if (mapKey == "precision") { if (std::holds_alternative<std::monostate>(data)) { - data = TDecimalData{ReadSmallInt(R"("precision")"), 0}; + const auto precision = ReadSmallInt(R"("precision")"); + if (0 == precision) { + ythrow TDeserializationException() << R"(invalid zero "precision")"; + } + data = TDecimalData{precision, std::nullopt}; } else if (std::holds_alternative<TDecimalData>(data)) { auto& decimalData = std::get<TDecimalData>(data); - if (decimalData.Precision == 0) { - decimalData.Precision = ReadSmallInt(R"("precision")"); + if (!decimalData.Precision.has_value()) { + const auto precision = ReadSmallInt(R"("precision")"); + if (0 == precision) { + ythrow TDeserializationException() << R"(invalid zero "precision")"; + } + decimalData.Precision = precision; } else { ythrow TDeserializationException() << R"(duplicate key "precision")"; } @@ -175,10 +186,10 @@ namespace NTi::NIo { } } else if (mapKey == "scale") { if (std::holds_alternative<std::monostate>(data)) { - data = TDecimalData{0, ReadSmallInt(R"("scale")")}; + data = TDecimalData{std::nullopt, ReadSmallInt(R"("scale")")}; } else if (std::holds_alternative<TDecimalData>(data)) { auto& decimalData = std::get<TDecimalData>(data); - if (decimalData.Scale == 0) { + if (!decimalData.Scale.has_value()) { decimalData.Scale = ReadSmallInt(R"("scale")"); } else { ythrow TDeserializationException() << R"(duplicate key "scale")"; @@ -272,15 +283,15 @@ namespace NTi::NIo { auto& decimalData = std::get<TDecimalData>(data); - if (decimalData.Precision == 0) { + if (!decimalData.Precision.has_value()) { ythrow TDeserializationException() << R"(missing required key "precision" for type Decimal)"; } - if (decimalData.Scale == 0) { + if (!decimalData.Scale.has_value()) { ythrow TDeserializationException() << R"(missing required key "scale" for type Decimal)"; } - return Factory_->DecimalRaw(decimalData.Precision, decimalData.Scale); + return Factory_->DecimalRaw(decimalData.Precision.value(), decimalData.Scale.value()); } case ETypeName::Json: type = TJsonType::InstanceRaw(); @@ -420,8 +431,8 @@ namespace NTi::NIo { auto result = event.AsScalar().AsInt64(); - if (result <= 0) { - ythrow TDeserializationException() << what << " must be greater than zero"; + if (result < 0) { + ythrow TDeserializationException() << what << " must be greater or equal to zero"; } if (result > Max<ui8>()) { diff --git a/library/cpp/type_info/ut/type_deserialize.cpp b/library/cpp/type_info/ut/type_deserialize.cpp index 9e93a26bee..7d5f60bad0 100644 --- a/library/cpp/type_info/ut/type_deserialize.cpp +++ b/library/cpp/type_info/ut/type_deserialize.cpp @@ -120,6 +120,40 @@ TEST(TypeDeserialize, Decimal) { ASSERT_DESERIALIZED_EQ(NTi::Decimal(20, 10), R"({type_name=decimal; precision=20; scale=10})"); ASSERT_DESERIALIZED_EQ(NTi::Decimal(20, 10), R"({scale=10; type_name=decimal; precision=20})"); ASSERT_DESERIALIZED_EQ(NTi::Decimal(10, 10), R"({type_name=decimal; precision=10; scale=10})"); + ASSERT_DESERIALIZED_EQ(NTi::Decimal(10, 0), R"({type_name=decimal; precision=10; scale=0})"); +} + +TEST(TypeDeserialize, DecimalBadTypeParameters) { + UNIT_ASSERT_EXCEPTION_CONTAINS( + []() { + NTi::NIo::DeserializeYson(*NTi::HeapFactory(), R"({type_name=decimal; precision=0; scale=10})"); + }(), + NTi::TDeserializationException, R"(invalid zero "precision")"); + UNIT_ASSERT_EXCEPTION_CONTAINS( + []() { + NTi::NIo::DeserializeYson(*NTi::HeapFactory(), R"({type_name=decimal; precision=-2; scale=10})"); + }(), + NTi::TDeserializationException, R"("precision" must be greater or equal to zero)"); + UNIT_ASSERT_EXCEPTION_CONTAINS( + []() { + NTi::NIo::DeserializeYson(*NTi::HeapFactory(), R"({type_name=decimal; precision=2; scale=-2})"); + }(), + NTi::TDeserializationException, R"("scale" must be greater or equal to zero)"); + UNIT_ASSERT_EXCEPTION_CONTAINS( + []() { + NTi::NIo::DeserializeYson(*NTi::HeapFactory(), R"({type_name=decimal; precision=2; scale=-2})"); + }(), + NTi::TDeserializationException, R"("scale" must be greater or equal to zero)"); + UNIT_ASSERT_EXCEPTION_CONTAINS( + []() { + NTi::NIo::DeserializeYson(*NTi::HeapFactory(), R"({type_name=decimal; precision=1000; scale=2})"); + }(), + NTi::TDeserializationException, R"("precision" is too big)"); + UNIT_ASSERT_EXCEPTION_CONTAINS( + []() { + NTi::NIo::DeserializeYson(*NTi::HeapFactory(), R"({type_name=decimal; precision=2; scale=1000})"); + }(), + NTi::TDeserializationException, R"("scale" is too big)"); } TEST(TypeDeserialize, DecimalMissingTypeParameters) { |