diff --git a/README.md b/README.md
index 5d9cd4c0a6b..c2e8f3cbdb0 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,5 @@
+**cpprestsdk is in maintenance mode and we do not recommend its use in new projects. We will continue to fix critical bugs and address security issues.**
+
## Welcome!
The C++ REST SDK is a Microsoft project for cloud-based client-server communication in native code using a modern asynchronous C++ API design. This project aims to help C++ developers connect to and interact with services.
@@ -59,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?
diff --git a/Release/CMakeLists.txt b/Release/CMakeLists.txt
index b8f3809dbc5..14e43cedcd5 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/base_uri.h b/Release/include/cpprest/base_uri.h
index 7c6943119c0..7e96b6c016b 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/include/cpprest/details/SafeInt3.hpp b/Release/include/cpprest/details/SafeInt3.hpp
index 950ac801724..e6276f949bb 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;
}
diff --git a/Release/include/cpprest/details/cpprest_compat.h b/Release/include/cpprest/details/cpprest_compat.h
index 6dae41d8d9b..bf10747987a 100644
--- a/Release/include/cpprest/details/cpprest_compat.h
+++ b/Release/include/cpprest/details/cpprest_compat.h
@@ -71,12 +71,20 @@
#ifdef _NO_ASYNCRTIMP
#define _ASYNCRTIMP
+#define _ASYNCRTIMP_TYPEINFO
#else // ^^^ _NO_ASYNCRTIMP ^^^ // vvv !_NO_ASYNCRTIMP vvv
#ifdef _ASYNCRT_EXPORT
#define _ASYNCRTIMP __declspec(dllexport)
#else // ^^^ _ASYNCRT_EXPORT ^^^ // vvv !_ASYNCRT_EXPORT vvv
#define _ASYNCRTIMP __declspec(dllimport)
#endif // _ASYNCRT_EXPORT
+
+#if defined(_WIN32)
+#define _ASYNCRTIMP_TYPEINFO
+#else // ^^^ _WIN32 ^^^ // vvv !_WIN32 vvv
+#define _ASYNCRTIMP_TYPEINFO __attribute__((visibility("default")))
+#endif // _WIN32
+
#endif // _NO_ASYNCRTIMP
#ifdef CASABLANCA_DEPRECATION_NO_WARNINGS
diff --git a/Release/include/cpprest/details/http_constants.dat b/Release/include/cpprest/details/http_constants.dat
index c3b1a53cb60..3deb24a1460 100644
--- a/Release/include/cpprest/details/http_constants.dat
+++ b/Release/include/cpprest/details/http_constants.dat
@@ -190,6 +190,7 @@ DAT(expires_in, "expires_in")
DAT(grant_type, "grant_type")
DAT(redirect_uri, "redirect_uri")
DAT(refresh_token, "refresh_token")
+DAT(client_credentials, "client_credentials")
DAT(response_type, "response_type")
DAT(scope, "scope")
DAT(state, "state")
diff --git a/Release/include/cpprest/http_msg.h b/Release/include/cpprest/http_msg.h
index 50f05ef2138..55c0433c941 100644
--- a/Release/include/cpprest/http_msg.h
+++ b/Release/include/cpprest/http_msg.h
@@ -187,7 +187,7 @@ class header_names
///
/// Represents an HTTP error. This class holds an error message and an optional error code.
///
-class http_exception : public std::exception
+class _ASYNCRTIMP_TYPEINFO http_exception : public std::exception
{
public:
///
diff --git a/Release/include/cpprest/json.h b/Release/include/cpprest/json.h
index 8fbbf947f2a..9549f9b8d55 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/include/cpprest/oauth2.h b/Release/include/cpprest/oauth2.h
index 693ebbe34c8..b1ec3249969 100644
--- a/Release/include/cpprest/oauth2.h
+++ b/Release/include/cpprest/oauth2.h
@@ -284,6 +284,21 @@ class oauth2_config
return _request_token(ub);
}
+ ///
+ /// Fetches an access token from the token endpoint using client credentials grant type.
+ /// The task creates an HTTP request to the token_endpoint() using
+ /// client authentication as the authorization grant.
+ /// See: http://tools.ietf.org/html/rfc6749#section-4.4
+ ///
+ /// Task that fetches token(s) using client credentials.
+ pplx::task token_from_client_credentials()
+ {
+ uri_builder ub;
+ ub.append_query(
+ details::oauth2_strings::grant_type, details::oauth2_strings::client_credentials, false);
+ return _request_token(ub);
+ }
+
///
/// Returns enabled state of the configuration.
/// The oauth2_handler will perform OAuth 2.0 authentication only if
diff --git a/Release/include/cpprest/producerconsumerstream.h b/Release/include/cpprest/producerconsumerstream.h
index 28463372e44..3487c4606ff 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();
}
}
diff --git a/Release/include/cpprest/version.h b/Release/include/cpprest/version.h
index d8771581ad7..3f86f141fb9 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/Release/src/json/json.cpp b/Release/src/json/json.cpp
index f1f0865d87a..079ccae4739 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/http/client/oauth2_tests.cpp b/Release/tests/functional/http/client/oauth2_tests.cpp
index e1f5408588d..08bb12a652e 100644
--- a/Release/tests/functional/http/client/oauth2_tests.cpp
+++ b/Release/tests/functional/http/client/oauth2_tests.cpp
@@ -291,6 +291,74 @@ SUITE(oauth2_tests)
VERIFY_ARE_EQUAL(U("done"), m_oauth2_config.token().access_token());
}
+ TEST_FIXTURE(oauth2_test_setup, oauth2_token_from_client_credentials)
+ {
+ VERIFY_IS_FALSE(m_oauth2_config.is_enabled());
+
+ m_oauth2_config.set_user_agent(U("test_user_agent"));
+
+ // Fetch using HTTP Basic authentication.
+ {
+ m_scoped.server()->next_request().then([](test_request* request) {
+ VERIFY_ARE_EQUAL(request->m_method, methods::POST);
+
+ VERIFY_IS_TRUE(is_application_x_www_form_urlencoded(request));
+
+ VERIFY_ARE_EQUAL(
+ U("Basic MTIzQUJDOjQ1NkRFRg=="),
+ request->m_headers[header_names::authorization]);
+
+ VERIFY_ARE_EQUAL(
+ to_body_data(U("grant_type=client_credentials")),
+ request->m_body);
+
+ VERIFY_ARE_EQUAL(
+ U("test_user_agent"),
+ get_request_user_agent(request));
+
+ std::map headers;
+ headers[header_names::content_type] = mime_types::application_json;
+ request->reply(
+ status_codes::OK, U(""), headers, "{\"access_token\":\"xyzzy123\",\"token_type\":\"bearer\"}");
+ });
+
+ m_oauth2_config.token_from_client_credentials().wait();
+ VERIFY_ARE_EQUAL(U("xyzzy123"), m_oauth2_config.token().access_token());
+ VERIFY_IS_TRUE(m_oauth2_config.is_enabled());
+ }
+
+ // Fetch using client key & secret in request body (x-www-form-urlencoded).
+ {
+ m_scoped.server()->next_request().then([](test_request* request) {
+ VERIFY_IS_TRUE(is_application_x_www_form_urlencoded(request));
+
+ VERIFY_ARE_EQUAL(U(""), request->m_headers[header_names::authorization]);
+
+ VERIFY_ARE_EQUAL(
+ to_body_data(U("grant_type=client_credentials&client_id=123ABC&client_secret=456DEF")),
+ request->m_body);
+
+ VERIFY_ARE_EQUAL(U("test_user_agent"), get_request_user_agent(request));
+
+ std::map headers;
+ headers[header_names::content_type] = mime_types::application_json;
+ request->reply(
+ status_codes::OK, U(""), headers, "{\"access_token\":\"xyzzy123\",\"token_type\":\"bearer\"}");
+ });
+
+ m_oauth2_config.set_token(oauth2_token()); // Clear token.
+ VERIFY_IS_FALSE(m_oauth2_config.is_enabled());
+
+ m_oauth2_config.set_http_basic_auth(false);
+ m_oauth2_config.token_from_client_credentials().wait();
+
+ VERIFY_ARE_EQUAL(
+ U("xyzzy123"),
+ m_oauth2_config.token().access_token());
+ VERIFY_IS_TRUE(m_oauth2_config.is_enabled());
+ }
+ }
+
TEST_FIXTURE(oauth2_test_setup, oauth2_bearer_token)
{
m_oauth2_config.set_token(oauth2_token(U("12345678")));
diff --git a/Release/tests/functional/json/construction_tests.cpp b/Release/tests/functional/json/construction_tests.cpp
index 111b1454e1c..7a9275b301e 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();
diff --git a/Release/tests/functional/uri/constructor_tests.cpp b/Release/tests/functional/uri/constructor_tests.cpp
index ea6041c26a3..ffcf5ada272 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 d8fb45d91c4..3271898f606 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());
}
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 00000000000..869fdfe2b24
--- /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).
+
+
diff --git a/changelog.md b/changelog.md
index c547665912f..7a9b6dfe044 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