From 71a085c1dc79f7945522aef4ed5f7c289ff6e73c Mon Sep 17 00:00:00 2001 From: Aleksandar Fabijanic Date: Mon, 14 Oct 2024 06:48:45 -0500 Subject: [PATCH] chore(JSON): add stringify unicode tests #4707 (#4720) * chore(JSON): add stringify unicode tests #4707 * enh(Mutex): Error code for pthread_mutex_lock failure #4712 --- Foundation/include/Poco/Error.h | 3 + Foundation/include/Poco/Mutex_POSIX.h | 14 +++-- Foundation/include/Poco/Mutex_WIN32.h | 5 +- Foundation/include/Poco/RWLock_VX.h | 14 +++-- Foundation/src/Error.cpp | 7 ++- Foundation/src/Mutex_POSIX.cpp | 4 +- Foundation/src/Mutex_WIN32.cpp | 2 +- JSON/testsuite/src/JSONTest.cpp | 86 ++++++++++++++++++--------- 8 files changed, 88 insertions(+), 47 deletions(-) diff --git a/Foundation/include/Poco/Error.h b/Foundation/include/Poco/Error.h index 935ee2234..8f8c37442 100644 --- a/Foundation/include/Poco/Error.h +++ b/Foundation/include/Poco/Error.h @@ -43,6 +43,9 @@ public: static std::string getMessage(int errorCode); /// Utility function translating numeric error code to string. #endif + + static std::string getLastMessage(); + /// Utility function returning the last error message. }; diff --git a/Foundation/include/Poco/Mutex_POSIX.h b/Foundation/include/Poco/Mutex_POSIX.h index 6e6c42a52..de90eae56 100644 --- a/Foundation/include/Poco/Mutex_POSIX.h +++ b/Foundation/include/Poco/Mutex_POSIX.h @@ -20,8 +20,8 @@ #include "Poco/Foundation.h" #include "Poco/Exception.h" +#include "Poco/Error.h" #include -#include namespace Poco { @@ -56,8 +56,9 @@ protected: // inline void MutexImpl::lockImpl() { - if (pthread_mutex_lock(&_mutex)) - throw SystemException("cannot lock mutex"); + int rc; + if ((rc = pthread_mutex_lock(&_mutex))) + throw SystemException("cannot lock mutex", Error::getMessage(rc)); } @@ -69,14 +70,15 @@ inline bool MutexImpl::tryLockImpl() else if (rc == EBUSY) return false; else - throw SystemException("cannot lock mutex"); + throw SystemException("cannot lock mutex", Error::getMessage(rc)); } inline void MutexImpl::unlockImpl() { - if (pthread_mutex_unlock(&_mutex)) - throw SystemException("cannot unlock mutex"); + int rc; + if ((rc = pthread_mutex_unlock(&_mutex))) + throw SystemException("cannot unlock mutex", Error::getMessage(rc)); } diff --git a/Foundation/include/Poco/Mutex_WIN32.h b/Foundation/include/Poco/Mutex_WIN32.h index b99981b20..c0967a914 100644 --- a/Foundation/include/Poco/Mutex_WIN32.h +++ b/Foundation/include/Poco/Mutex_WIN32.h @@ -20,6 +20,7 @@ #include "Poco/Foundation.h" #include "Poco/Exception.h" +#include "Poco/Error.h" #include "Poco/UnWindows.h" @@ -55,7 +56,7 @@ inline void MutexImpl::lockImpl() } catch (...) { - throw SystemException("cannot lock mutex"); + throw SystemException("cannot lock mutex", Error::getLastMessage()); } } @@ -69,7 +70,7 @@ inline bool MutexImpl::tryLockImpl() catch (...) { } - throw SystemException("cannot lock mutex"); + throw SystemException("cannot lock mutex", Error::getLastMessage()); } diff --git a/Foundation/include/Poco/RWLock_VX.h b/Foundation/include/Poco/RWLock_VX.h index e5a18e052..cd0804d70 100644 --- a/Foundation/include/Poco/RWLock_VX.h +++ b/Foundation/include/Poco/RWLock_VX.h @@ -20,8 +20,8 @@ #include "Poco/Foundation.h" #include "Poco/Exception.h" +#include "Poco/Error.h" #include -#include namespace Poco { @@ -48,8 +48,9 @@ private: // inline void RWLockImpl::readLockImpl() { - if (pthread_mutex_lock(&_mutex)) - throw SystemException("cannot lock mutex"); + int rc = 0; + if ((rc = pthread_mutex_lock(&_mutex))) + throw SystemException("cannot lock mutex", Error::getMessage(rc)); } @@ -61,7 +62,7 @@ inline bool RWLockImpl::tryReadLockImpl() else if (rc == EBUSY) return false; else - throw SystemException("cannot lock mutex"); + throw SystemException("cannot lock mutex", Error::getMessage(rc)); } @@ -81,8 +82,9 @@ inline bool RWLockImpl::tryWriteLockImpl() inline void RWLockImpl::unlockImpl() { - if (pthread_mutex_unlock(&_mutex)) - throw SystemException("cannot unlock mutex"); + int rc = 0; + if ((rc = pthread_mutex_unlock(&_mutex))) + throw SystemException("cannot unlock mutex", Error::getMessage(rc)); } diff --git a/Foundation/src/Error.cpp b/Foundation/src/Error.cpp index 1bda8d9d3..78573ce2c 100644 --- a/Foundation/src/Error.cpp +++ b/Foundation/src/Error.cpp @@ -102,8 +102,13 @@ namespace Poco { return helper.message(); } - #endif +std::string Error::getLastMessage() +{ + return getMessage(last()); +} + + } // namespace Poco diff --git a/Foundation/src/Mutex_POSIX.cpp b/Foundation/src/Mutex_POSIX.cpp index 4661d929b..db344cc0e 100644 --- a/Foundation/src/Mutex_POSIX.cpp +++ b/Foundation/src/Mutex_POSIX.cpp @@ -131,7 +131,7 @@ bool MutexImpl::tryLockImpl(long milliseconds) else if (rc == ETIMEDOUT) return false; else - throw SystemException("cannot lock mutex"); + throw SystemException("cannot lock mutex", Error::getMessage(rc)); #else const int sleepMillis = 5; Timestamp now; @@ -142,7 +142,7 @@ bool MutexImpl::tryLockImpl(long milliseconds) if (rc == 0) return true; else if (rc != EBUSY) - throw SystemException("cannot lock mutex"); + throw SystemException("cannot lock mutex", Error::getMessage(rc)); #if defined(POCO_VXWORKS) struct timespec ts; ts.tv_sec = 0; diff --git a/Foundation/src/Mutex_WIN32.cpp b/Foundation/src/Mutex_WIN32.cpp index 446f4affc..4e6df8ac3 100644 --- a/Foundation/src/Mutex_WIN32.cpp +++ b/Foundation/src/Mutex_WIN32.cpp @@ -47,7 +47,7 @@ bool MutexImpl::tryLockImpl(long milliseconds) } catch (...) { - throw SystemException("cannot lock mutex"); + throw SystemException("cannot lock mutex", Error::getLastMessage()); } Sleep(sleepMillis); } diff --git a/JSON/testsuite/src/JSONTest.cpp b/JSON/testsuite/src/JSONTest.cpp index dec1e7a97..30cca35ca 100644 --- a/JSON/testsuite/src/JSONTest.cpp +++ b/JSON/testsuite/src/JSONTest.cpp @@ -1583,6 +1583,34 @@ void JSONTest::testStringify() " }\n" "}"; assertTrue (ostr.str() == str); + + { + std::string jsonStr = R"json({"default":"\u0007\u0007"})json"; + auto jsonStrUnescape = Poco::UTF8::unescape(jsonStr); + Poco::JSON::Parser parser; + Poco::Dynamic::Var result = parser.parse(jsonStr); + const auto & obj = result.extract(); + auto default_val = obj->get("default"); + Poco::JSON::Object::Ptr json = new Poco::JSON::Object(); + json->set("default", default_val); + std::stringstream ss; + json->stringify(ss); + assertEqual(ss.str(), jsonStr); + } + + { + std::string jsonStr = R"json({"default":"\u0050\u0050"})json"; + auto jsonStrUnescape = Poco::UTF8::unescape(jsonStr); + Poco::JSON::Parser parser; + Poco::Dynamic::Var result = parser.parse(jsonStr); + const auto & obj = result.extract(); + auto default_val = obj->get("default"); + Poco::JSON::Object::Ptr json = new Poco::JSON::Object(); + json->set("default", default_val); + std::stringstream ss; + json->stringify(ss); + assertEqual(ss.str(), jsonStrUnescape); + } } @@ -2375,52 +2403,52 @@ void JSONTest::testEnum() { SE_VALUE = 42 }; - + enum class SAMPLE_ENUM_CLASS { VALUE = 42 }; - + enum class SAMPLE_ENUM_CLASS_I8: Poco::Int8 { VALUE = 42 }; - + enum class SAMPLE_ENUM_CLASS_I16: Poco::Int16 { VALUE = 42 }; - + enum class SAMPLE_ENUM_CLASS_I32: Poco::Int32 { VALUE = 42 }; - + enum class SAMPLE_ENUM_CLASS_I64: Poco::Int64 { VALUE = 42 }; - + enum class SAMPLE_ENUM_CLASS_UI8: Poco::UInt8 { VALUE = 42 }; - + enum class SAMPLE_ENUM_CLASS_UI16: Poco::UInt16 { VALUE = 42 }; - + enum class SAMPLE_ENUM_CLASS_UI32: Poco::UInt32 { VALUE = 42 }; - + enum class SAMPLE_ENUM_CLASS_UI64: Poco::UInt64 { VALUE = 42 }; - + { Poco::JSON::Object::Ptr obj = new Poco::JSON::Object(); obj->set("simple_enum", SE_VALUE); @@ -2428,11 +2456,11 @@ void JSONTest::testEnum() std::string expected = "{\"simple_enum\":42}"; std::string result = var.convert(); assertEquals(expected, result); - + SAMPLE_ENUM se = obj->get("simple_enum").extract(); assertTrue(se == SE_VALUE); } - + { Poco::JSON::Object::Ptr obj = new Poco::JSON::Object(); obj->set("enum_class", SAMPLE_ENUM_CLASS::VALUE); @@ -2440,11 +2468,11 @@ void JSONTest::testEnum() std::string expected = "{\"enum_class\":42}"; std::string result = var.convert(); assertEquals(expected, result); - + SAMPLE_ENUM_CLASS se = obj->get("enum_class").extract(); assertTrue(se == SAMPLE_ENUM_CLASS::VALUE); } - + { Poco::JSON::Object::Ptr obj = new Poco::JSON::Object(); obj->set("enum_class_i8", SAMPLE_ENUM_CLASS_I8::VALUE); @@ -2452,11 +2480,11 @@ void JSONTest::testEnum() std::string expected = "{\"enum_class_i8\":42}"; std::string result = var.convert(); assertEquals(expected, result); - + SAMPLE_ENUM_CLASS_I8 se = obj->get("enum_class_i8").extract(); assertTrue(se == SAMPLE_ENUM_CLASS_I8::VALUE); } - + { Poco::JSON::Object::Ptr obj = new Poco::JSON::Object(); obj->set("enum_class_i16", SAMPLE_ENUM_CLASS_I16::VALUE); @@ -2464,11 +2492,11 @@ void JSONTest::testEnum() std::string expected = "{\"enum_class_i16\":42}"; std::string result = var.convert(); assertEquals(expected, result); - + SAMPLE_ENUM_CLASS_I16 se = obj->get("enum_class_i16").extract(); assertTrue(se == SAMPLE_ENUM_CLASS_I16::VALUE); } - + { Poco::JSON::Object::Ptr obj = new Poco::JSON::Object(); obj->set("enum_class_i32", SAMPLE_ENUM_CLASS_I32::VALUE); @@ -2476,11 +2504,11 @@ void JSONTest::testEnum() std::string expected = "{\"enum_class_i32\":42}"; std::string result = var.convert(); assertEquals(expected, result); - + SAMPLE_ENUM_CLASS_I32 se = obj->get("enum_class_i32").extract(); assertTrue(se == SAMPLE_ENUM_CLASS_I32::VALUE); } - + { Poco::JSON::Object::Ptr obj = new Poco::JSON::Object(); obj->set("enum_class_i64", SAMPLE_ENUM_CLASS_I64::VALUE); @@ -2488,11 +2516,11 @@ void JSONTest::testEnum() std::string expected = "{\"enum_class_i64\":42}"; std::string result = var.convert(); assertEquals(expected, result); - + SAMPLE_ENUM_CLASS_I64 se = obj->get("enum_class_i64").extract(); assertTrue(se == SAMPLE_ENUM_CLASS_I64::VALUE); } - + { Poco::JSON::Object::Ptr obj = new Poco::JSON::Object(); obj->set("enum_class_ui8", SAMPLE_ENUM_CLASS_UI8::VALUE); @@ -2500,11 +2528,11 @@ void JSONTest::testEnum() std::string expected = "{\"enum_class_ui8\":42}"; std::string result = var.convert(); assertEquals(expected, result); - + SAMPLE_ENUM_CLASS_UI8 se = obj->get("enum_class_ui8").extract(); assertTrue(se == SAMPLE_ENUM_CLASS_UI8::VALUE); } - + { Poco::JSON::Object::Ptr obj = new Poco::JSON::Object(); obj->set("enum_class_ui16", SAMPLE_ENUM_CLASS_UI16::VALUE); @@ -2512,11 +2540,11 @@ void JSONTest::testEnum() std::string expected = "{\"enum_class_ui16\":42}"; std::string result = var.convert(); assertEquals(expected, result); - + SAMPLE_ENUM_CLASS_UI16 se = obj->get("enum_class_ui16").extract(); assertTrue(se == SAMPLE_ENUM_CLASS_UI16::VALUE); } - + { Poco::JSON::Object::Ptr obj = new Poco::JSON::Object(); obj->set("enum_class_ui32", SAMPLE_ENUM_CLASS_UI32::VALUE); @@ -2524,11 +2552,11 @@ void JSONTest::testEnum() std::string expected = "{\"enum_class_ui32\":42}"; std::string result = var.convert(); assertEquals(expected, result); - + SAMPLE_ENUM_CLASS_UI32 se = obj->get("enum_class_ui32").extract(); assertTrue(se == SAMPLE_ENUM_CLASS_UI32::VALUE); } - + { Poco::JSON::Object::Ptr obj = new Poco::JSON::Object(); obj->set("enum_class_ui64", SAMPLE_ENUM_CLASS_UI64::VALUE); @@ -2536,7 +2564,7 @@ void JSONTest::testEnum() std::string expected = "{\"enum_class_ui64\":42}"; std::string result = var.convert(); assertEquals(expected, result); - + SAMPLE_ENUM_CLASS_UI64 se = obj->get("enum_class_ui64").extract(); assertTrue(se == SAMPLE_ENUM_CLASS_UI64::VALUE); }