From 5408f1dc9664d8ed11042787be134fdf6d5b19fe Mon Sep 17 00:00:00 2001 From: NN Date: Sat, 23 May 2020 16:40:58 +0300 Subject: [PATCH 01/10] Add constructor from all integer types. Fixes #1428 --- Release/include/cpprest/json.h | 62 ++++++++++++++----- Release/src/json/json.cpp | 37 ++++++++--- .../functional/json/construction_tests.cpp | 55 ++++++++++++++++ 3 files changed, 130 insertions(+), 24 deletions(-) diff --git a/Release/include/cpprest/json.h b/Release/include/cpprest/json.h index 8fbbf947f2..84bf2b89d6 100644 --- a/Release/include/cpprest/json.h +++ b/Release/include/cpprest/json.h @@ -100,25 +100,37 @@ class value /// Constructor creating a JSON number value /// /// The C++ value to create a JSON value from - _ASYNCRTIMP value(int32_t value); + _ASYNCRTIMP value(int value); /// /// Constructor creating a JSON number value /// /// The C++ value to create a JSON value from - _ASYNCRTIMP value(uint32_t value); + _ASYNCRTIMP value(unsigned value); /// /// Constructor creating a JSON number value /// /// The C++ value to create a JSON value from - _ASYNCRTIMP value(int64_t value); + _ASYNCRTIMP value(long value); /// /// Constructor creating a JSON number value /// /// The C++ value to create a JSON value from - _ASYNCRTIMP value(uint64_t value); + _ASYNCRTIMP value(unsigned long value); + + /// + /// Constructor creating a JSON number value + /// + /// The C++ value to create a JSON value from + _ASYNCRTIMP value(long long value); + + /// + /// Constructor creating a JSON number value + /// + /// The C++ value to create a JSON value from + _ASYNCRTIMP value(unsigned long long value); /// /// Constructor creating a JSON number value @@ -222,28 +234,42 @@ class value /// /// The C++ value to create a JSON value from /// A JSON number value - static _ASYNCRTIMP value __cdecl number(int32_t value); + static _ASYNCRTIMP value __cdecl number(int value); + + /// + /// Creates a number value + /// + /// The C++ value to create a JSON value from + /// A JSON number value + static _ASYNCRTIMP value __cdecl number(unsigned value); + + /// + /// Creates a number value + /// + /// The C++ value to create a JSON value from + /// A JSON number value + static _ASYNCRTIMP value __cdecl number(long value); /// /// Creates a number value /// /// The C++ value to create a JSON value from /// A JSON number value - static _ASYNCRTIMP value __cdecl number(uint32_t value); + static _ASYNCRTIMP value __cdecl number(unsigned long value); /// /// Creates a number value /// /// The C++ value to create a JSON value from /// A JSON number value - static _ASYNCRTIMP value __cdecl number(int64_t value); + static _ASYNCRTIMP value __cdecl number(long long value); /// /// Creates a number value /// /// The C++ value to create a JSON value from /// A JSON number value - static _ASYNCRTIMP value __cdecl number(uint64_t value); + static _ASYNCRTIMP value __cdecl number(unsigned long long value); /// /// Creates a Boolean value @@ -1218,10 +1244,12 @@ class number // convert to unsigned int64). This helps handling number objects e.g. comparing two numbers. number(double value) : m_value(value), m_type(double_type) {} - number(int32_t value) : m_intval(value), m_type(value < 0 ? signed_type : unsigned_type) {} - number(uint32_t value) : m_intval(value), m_type(unsigned_type) {} - number(int64_t value) : m_intval(value), m_type(value < 0 ? signed_type : unsigned_type) {} - number(uint64_t value) : m_uintval(value), m_type(unsigned_type) {} + number(int value) : m_intval(value), m_type(value < 0 ? signed_type : unsigned_type) {} + number(unsigned value) : m_intval(value), m_type(unsigned_type) {} + number(long value) : m_intval(value), m_type(value < 0 ? signed_type : unsigned_type) {} + number(unsigned long value) : m_uintval(value), m_type(unsigned_type) {} + number(long long value) : m_intval(value), m_type(value < 0 ? signed_type : unsigned_type) { } + number(unsigned long long value) : m_uintval(value), m_type(unsigned_type) { } public: /// @@ -1438,10 +1466,12 @@ class _Number : public _Value { public: _Number(double value) : m_number(value) {} - _Number(int32_t value) : m_number(value) {} - _Number(uint32_t value) : m_number(value) {} - _Number(int64_t value) : m_number(value) {} - _Number(uint64_t value) : m_number(value) {} + _Number(int value) : m_number(value) {} + _Number(unsigned value) : m_number(value) {} + _Number(long value) : m_number(value) {} + _Number(unsigned long value) : m_number(value) {} + _Number(long long value) : m_number(value) { } + _Number(unsigned long long value) : m_number(value) { } virtual std::unique_ptr<_Value> _copy_value() { return utility::details::make_unique<_Number>(*this); } diff --git a/Release/src/json/json.cpp b/Release/src/json/json.cpp index f1f0865d87..079ccae473 100644 --- a/Release/src/json/json.cpp +++ b/Release/src/json/json.cpp @@ -38,7 +38,7 @@ web::json::value::value() { } -web::json::value::value(int32_t value) +web::json::value::value(int value) : m_value(utility::details::make_unique(value)) #ifdef ENABLE_JSON_VALUE_VISUALIZER , m_kind(value::Number) @@ -46,7 +46,7 @@ web::json::value::value(int32_t value) { } -web::json::value::value(uint32_t value) +web::json::value::value(unsigned value) : m_value(utility::details::make_unique(value)) #ifdef ENABLE_JSON_VALUE_VISUALIZER , m_kind(value::Number) @@ -54,7 +54,8 @@ web::json::value::value(uint32_t value) { } -web::json::value::value(int64_t value) + +web::json::value::value(long value) : m_value(utility::details::make_unique(value)) #ifdef ENABLE_JSON_VALUE_VISUALIZER , m_kind(value::Number) @@ -62,7 +63,23 @@ web::json::value::value(int64_t value) { } -web::json::value::value(uint64_t value) +web::json::value::value(unsigned long value) + : m_value(utility::details::make_unique(value)) +#ifdef ENABLE_JSON_VALUE_VISUALIZER + , m_kind(value::Number) +#endif +{ +} + +web::json::value::value(long long value) + : m_value(utility::details::make_unique(value)) +#ifdef ENABLE_JSON_VALUE_VISUALIZER + , m_kind(value::Number) +#endif +{ +} + +web::json::value::value(unsigned long long value) : m_value(utility::details::make_unique(value)) #ifdef ENABLE_JSON_VALUE_VISUALIZER , m_kind(value::Number) @@ -162,13 +179,17 @@ web::json::value web::json::value::null() { return web::json::value(); } web::json::value web::json::value::number(double value) { return web::json::value(value); } -web::json::value web::json::value::number(int32_t value) { return web::json::value(value); } +web::json::value web::json::value::number(int value) { return web::json::value(value); } + +web::json::value web::json::value::number(unsigned value) { return web::json::value(value); } + +web::json::value web::json::value::number(long value) { return web::json::value(value); } -web::json::value web::json::value::number(uint32_t value) { return web::json::value(value); } +web::json::value web::json::value::number(unsigned long value) { return web::json::value(value); } -web::json::value web::json::value::number(int64_t value) { return web::json::value(value); } +web::json::value web::json::value::number(long long value) { return web::json::value(value); } -web::json::value web::json::value::number(uint64_t value) { return web::json::value(value); } +web::json::value web::json::value::number(unsigned long long value) { return web::json::value(value); } web::json::value web::json::value::boolean(bool value) { return web::json::value(value); } diff --git a/Release/tests/functional/json/construction_tests.cpp b/Release/tests/functional/json/construction_tests.cpp index 111b1454e1..7a9275b301 100644 --- a/Release/tests/functional/json/construction_tests.cpp +++ b/Release/tests/functional/json/construction_tests.cpp @@ -50,6 +50,61 @@ SUITE(construction_tests) VERIFY_ARE_EQUAL(U("null"), arr[1].serialize()); } + TEST(int_assignment_op) + { + json::value v; + v = static_cast(1); + VERIFY_ARE_EQUAL(U("1"), v.serialize()); + + v = static_cast(1); + VERIFY_ARE_EQUAL(U("1"), v.serialize()); + + v = static_cast(1); + VERIFY_ARE_EQUAL(U("1"), v.serialize()); + + v = static_cast(1); + VERIFY_ARE_EQUAL(U("1"), v.serialize()); + + v = static_cast(1); + VERIFY_ARE_EQUAL(U("1"), v.serialize()); + + v = static_cast(1); + VERIFY_ARE_EQUAL(U("1"), v.serialize()); + } + + TEST(int_ctor) + { + { + json::value v(static_cast(1)); + VERIFY_ARE_EQUAL(U("1"), v.serialize()); + } + + { + json::value v(static_cast(1)); + VERIFY_ARE_EQUAL(U("1"), v.serialize()); + } + + { + json::value v(static_cast(1)); + VERIFY_ARE_EQUAL(U("1"), v.serialize()); + } + + { + json::value v(static_cast(1)); + VERIFY_ARE_EQUAL(U("1"), v.serialize()); + } + + { + json::value v(static_cast(1)); + VERIFY_ARE_EQUAL(U("1"), v.serialize()); + } + + { + json::value v(static_cast(1)); + VERIFY_ARE_EQUAL(U("1"), v.serialize()); + } + } + TEST(copy_ctor_array) { json::value arr = json::value::array(); From 06363bc78325e9541dd9fa2a6eab291d3f3c8596 Mon Sep 17 00:00:00 2001 From: NN <580536+NN---@users.noreply.github.com> Date: Thu, 10 Mar 2022 22:38:13 +0200 Subject: [PATCH 02/10] Update Release/include/cpprest/json.h Co-authored-by: Charlie Barto --- Release/include/cpprest/json.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Release/include/cpprest/json.h b/Release/include/cpprest/json.h index 84bf2b89d6..78e20c4d9e 100644 --- a/Release/include/cpprest/json.h +++ b/Release/include/cpprest/json.h @@ -1248,8 +1248,8 @@ class number number(unsigned value) : m_intval(value), m_type(unsigned_type) {} number(long value) : m_intval(value), m_type(value < 0 ? signed_type : unsigned_type) {} number(unsigned long value) : m_uintval(value), m_type(unsigned_type) {} - number(long long value) : m_intval(value), m_type(value < 0 ? signed_type : unsigned_type) { } - number(unsigned long long value) : m_uintval(value), m_type(unsigned_type) { } + number(long long value) : m_intval(value), m_type(value < 0 ? signed_type : unsigned_type) {} + number(unsigned long long value) : m_uintval(value), m_type(unsigned_type) {} public: /// From 3eac925ada68dc2df6a5b688fdfb79865e04a6f3 Mon Sep 17 00:00:00 2001 From: NN <580536+NN---@users.noreply.github.com> Date: Thu, 10 Mar 2022 22:38:30 +0200 Subject: [PATCH 03/10] Update Release/include/cpprest/json.h Co-authored-by: Charlie Barto --- Release/include/cpprest/json.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Release/include/cpprest/json.h b/Release/include/cpprest/json.h index 78e20c4d9e..9549f9b8d5 100644 --- a/Release/include/cpprest/json.h +++ b/Release/include/cpprest/json.h @@ -1470,8 +1470,8 @@ class _Number : public _Value _Number(unsigned value) : m_number(value) {} _Number(long value) : m_number(value) {} _Number(unsigned long value) : m_number(value) {} - _Number(long long value) : m_number(value) { } - _Number(unsigned long long value) : m_number(value) { } + _Number(long long value) : m_number(value) {} + _Number(unsigned long long value) : m_number(value) {} virtual std::unique_ptr<_Value> _copy_value() { return utility::details::make_unique<_Number>(*this); } From 3308d97280a076327d3f2abe31253323274a7692 Mon Sep 17 00:00:00 2001 From: Fighter19 <1475802+Fighter19@users.noreply.github.com> Date: Fri, 1 Jul 2022 14:19:04 +0200 Subject: [PATCH 04/10] Fix likely typo in SafeInt3.hpp, that results in error with clang 15 --- Release/include/cpprest/details/SafeInt3.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Release/include/cpprest/details/SafeInt3.hpp b/Release/include/cpprest/details/SafeInt3.hpp index 950ac80172..e6276f949b 100644 --- a/Release/include/cpprest/details/SafeInt3.hpp +++ b/Release/include/cpprest/details/SafeInt3.hpp @@ -1574,7 +1574,7 @@ class SafeCastHelper } template - static void CastThrow(bool b, T& t) SAFEINT_CPP_THROW + static void CastThrow(T t, bool& b) SAFEINT_CPP_THROW { b = !!t; } From a57f4591876a4565ce21ee1bac1904cb49adc424 Mon Sep 17 00:00:00 2001 From: "microsoft-github-policy-service[bot]" <77245923+microsoft-github-policy-service[bot]@users.noreply.github.com> Date: Wed, 31 Aug 2022 15:23:18 +0000 Subject: [PATCH 05/10] Microsoft mandatory file --- SECURITY.md | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000000..869fdfe2b2 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,41 @@ + + +## Security + +Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). + +If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below. + +## Reporting Security Issues + +**Please do not report security vulnerabilities through public GitHub issues.** + +Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). + +If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey). + +You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). + +Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: + + * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) + * Full paths of source file(s) related to the manifestation of the issue + * The location of the affected source code (tag/branch/commit or direct URL) + * Any special configuration required to reproduce the issue + * Step-by-step instructions to reproduce the issue + * Proof-of-concept or exploit code (if possible) + * Impact of the issue, including how an attacker might exploit the issue + +This information will help us triage your report more quickly. + +If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs. + +## Preferred Languages + +We prefer all communications to be in English. + +## Policy + +Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). + + From 98ee36dacd1844a5a6861d4a8cc20ec3aad5c9e9 Mon Sep 17 00:00:00 2001 From: Ye Cao Date: Mon, 19 Sep 2022 22:50:48 +0800 Subject: [PATCH 06/10] Fix typo --- Release/include/cpprest/producerconsumerstream.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Release/include/cpprest/producerconsumerstream.h b/Release/include/cpprest/producerconsumerstream.h index 28463372e4..3487c4606f 100644 --- a/Release/include/cpprest/producerconsumerstream.h +++ b/Release/include/cpprest/producerconsumerstream.h @@ -584,7 +584,7 @@ class basic_producer_consumer_buffer : public streams::details::streambuf_state_ // If front block is not empty - we are done if (m_blocks.front()->rd_chars_left() > 0) break; - // The block has no more data to be read. Relase the block + // The block has no more data to be read. Release the block m_blocks.pop_front(); } } From 9c654889efb6f5bda69fe8f52b3f7d3d3fb56cd8 Mon Sep 17 00:00:00 2001 From: Charlie Barto Date: Wed, 16 Nov 2022 13:07:45 -0800 Subject: [PATCH 07/10] Remove email list from the readme It's better to use issues, so everyone can see the responses. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e7d91abeaa..c2e8f3cbdb 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ target_link_libraries(main PRIVATE cpprestsdk::cpprest) Is there a feature missing that you'd like to see, or found a bug that you have a fix for? Or do you have an idea or just interest in helping out in building the library? Let us know and we'd love to work with you. For a good starting point on where we are headed and feature ideas, take a look at our [requested features and bugs](https://github.com/Microsoft/cpprestsdk/issues). -Big or small we'd like to take your [contributions](https://github.com/Microsoft/cpprestsdk/wiki/Make-a-contribution-and-report-issues) back to help improve the C++ Rest SDK for everyone. If interested contact us askcasablanca at Microsoft dot com. +Big or small we'd like to take your [contributions](https://github.com/Microsoft/cpprestsdk/wiki/Make-a-contribution-and-report-issues) back to help improve the C++ Rest SDK for everyone. ## Having Trouble? From 006271f6a782141a7c9cef17e6d76f080c022add Mon Sep 17 00:00:00 2001 From: Charlie Barto Date: Mon, 4 Dec 2023 19:58:39 -0800 Subject: [PATCH 08/10] make Uri.is_host_loopback() only return true for localhost and 127.0.0.1 exactly --- Release/include/cpprest/base_uri.h | 5 +++-- Release/tests/functional/uri/constructor_tests.cpp | 5 +++++ Release/tests/functional/uri/diagnostic_tests.cpp | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Release/include/cpprest/base_uri.h b/Release/include/cpprest/base_uri.h index 7c6943119c..7e96b6c016 100644 --- a/Release/include/cpprest/base_uri.h +++ b/Release/include/cpprest/base_uri.h @@ -296,13 +296,14 @@ class uri /// A loopback URI is one which refers to a hostname or ip address with meaning only on the local machine. /// /// - /// Examples include "localhost", or ip addresses in the loopback range (127.0.0.0/24). + /// Examples include "localhost", or "127.0.0.1". The only URIs for which this method returns true are "127.0.0.1", and "localhost", + /// all other URIs return false /// /// true if this URI references the local host, false otherwise. bool is_host_loopback() const { return !is_empty() && - ((host() == _XPLATSTR("localhost")) || (host().size() > 4 && host().substr(0, 4) == _XPLATSTR("127."))); + ((host() == _XPLATSTR("localhost")) || (host() == _XPLATSTR("127.0.0.1"))); } /// diff --git a/Release/tests/functional/uri/constructor_tests.cpp b/Release/tests/functional/uri/constructor_tests.cpp index ea6041c26a..ffcf5ada27 100644 --- a/Release/tests/functional/uri/constructor_tests.cpp +++ b/Release/tests/functional/uri/constructor_tests.cpp @@ -24,6 +24,11 @@ namespace uri_tests { SUITE(constructor_tests) { + TEST(not_really_a_loopback_uri) + { + uri u(uri::encode_uri(U("https://127.evil.com"))); + VERIFY_IS_FALSE(u.is_host_loopback()); + } TEST(parsing_constructor_char) { uri u(uri::encode_uri(U("net.tcp://steve:@testname.com:81/bleh%?qstring#goo"))); diff --git a/Release/tests/functional/uri/diagnostic_tests.cpp b/Release/tests/functional/uri/diagnostic_tests.cpp index d8fb45d91c..3271898f60 100644 --- a/Release/tests/functional/uri/diagnostic_tests.cpp +++ b/Release/tests/functional/uri/diagnostic_tests.cpp @@ -82,7 +82,7 @@ SUITE(diagnostic_tests) VERIFY_IS_FALSE(uri(U("http://bleh/?qstring")).is_host_loopback()); VERIFY_IS_FALSE(uri(U("http://+*/?qstring")).is_host_loopback()); VERIFY_IS_TRUE(uri(U("http://127.0.0.1/")).is_host_loopback()); - VERIFY_IS_TRUE(uri(U("http://127.155.0.1/")).is_host_loopback()); + VERIFY_IS_FALSE(uri(U("http://127.155.0.1/")).is_host_loopback()); VERIFY_IS_FALSE(uri(U("http://128.0.0.1/")).is_host_loopback()); } From 411a109150b270f23c8c97fa4ec9a0a4a98cdecf Mon Sep 17 00:00:00 2001 From: Charlie Barto Date: Mon, 4 Dec 2023 20:23:31 -0800 Subject: [PATCH 09/10] mint 2.10.19 --- Release/CMakeLists.txt | 2 +- Release/include/cpprest/version.h | 2 +- changelog.md | 9 +++++++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/Release/CMakeLists.txt b/Release/CMakeLists.txt index b8f3809dbc..14e43cedcd 100644 --- a/Release/CMakeLists.txt +++ b/Release/CMakeLists.txt @@ -11,7 +11,7 @@ endif() set(CPPREST_VERSION_MAJOR 2) set(CPPREST_VERSION_MINOR 10) -set(CPPREST_VERSION_REVISION 18) +set(CPPREST_VERSION_REVISION 19) enable_testing() diff --git a/Release/include/cpprest/version.h b/Release/include/cpprest/version.h index d8771581ad..3f86f141fb 100644 --- a/Release/include/cpprest/version.h +++ b/Release/include/cpprest/version.h @@ -5,6 +5,6 @@ */ #define CPPREST_VERSION_MINOR 10 #define CPPREST_VERSION_MAJOR 2 -#define CPPREST_VERSION_REVISION 18 +#define CPPREST_VERSION_REVISION 19 #define CPPREST_VERSION (CPPREST_VERSION_MAJOR * 100000 + CPPREST_VERSION_MINOR * 100 + CPPREST_VERSION_REVISION) diff --git a/changelog.md b/changelog.md index c547665912..7a9b6dfe04 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,12 @@ +cpprestsdk (2.10.19) +* PR#1982 make Uri.is_host_loopback() only return true for localhost and 127.0.0.1 exactly. + The old behavior could potentially return "true" for URLs that were not, in fact, local, + and this could cause security issues if is_host_loopback was used in certain ways. +* PR#1711 Fix likely typo in SafeInt3.hpp, that results in error with clang 15 +* PR#1496 Support for oauth2 with "client_credentials" grant type. +* PR#1429 Add constructor from all integer types for json value. +* PR#1577 export http_exception for non Windows builds using visibility macros. + cpprestsdk (2.10.18) * PR#1571 Add ability to parse and emit the NT Epoch 1601-01-01T00:00:00Z * PR#1571 Update vcpkg submodule From 0b1ce318a757bbfb89bdb0fffb61ca4e38dc3b33 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 22 Nov 2024 17:52:57 -0800 Subject: [PATCH 10/10] Include `` for `system_clock` (#1811) --- Release/tests/common/UnitTestpp/src/TestRunner.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Release/tests/common/UnitTestpp/src/TestRunner.cpp b/Release/tests/common/UnitTestpp/src/TestRunner.cpp index 807a0e3b10..69551f3e2e 100644 --- a/Release/tests/common/UnitTestpp/src/TestRunner.cpp +++ b/Release/tests/common/UnitTestpp/src/TestRunner.cpp @@ -39,6 +39,7 @@ #include #include #else +#include #include #endif