diff --git a/include/jwt/algorithm.hpp b/include/jwt/algorithm.hpp index b013a39..9abe20c 100644 --- a/include/jwt/algorithm.hpp +++ b/include/jwt/algorithm.hpp @@ -47,6 +47,7 @@ SOFTWARE. #include "jwt/string_view.hpp" #include "jwt/error_codes.hpp" #include "jwt/base64.hpp" +#include "jwt/config.hpp" namespace jwt { @@ -220,7 +221,7 @@ enum class algorithm * Convert the algorithm enum class type to * its stringified form. */ -inline jwt::string_view alg_to_str(enum algorithm alg) noexcept +inline jwt::string_view alg_to_str(SCOPED_ENUM algorithm alg) noexcept { switch (alg) { case algorithm::HS256: return "HS256"; @@ -245,7 +246,7 @@ inline jwt::string_view alg_to_str(enum algorithm alg) noexcept * Convert stringified algorithm to enum class. * The string comparison is case insesitive. */ -inline enum algorithm str_to_alg(const jwt::string_view alg) noexcept +inline SCOPED_ENUM algorithm str_to_alg(const jwt::string_view alg) noexcept { if (!alg.length()) return algorithm::NONE; diff --git a/include/jwt/base64.hpp b/include/jwt/base64.hpp index 8965cb3..1f2e921 100644 --- a/include/jwt/base64.hpp +++ b/include/jwt/base64.hpp @@ -27,6 +27,7 @@ SOFTWARE. #include #include #include +#include "jwt/config.hpp" #include "jwt/string_view.hpp" namespace jwt { @@ -61,8 +62,7 @@ public: public: constexpr char at(size_t pos) const noexcept { - assert (pos < chars_.size()); - return chars_.at(pos); + return X_ASSERT(pos < chars_.size()), chars_.at(pos); } private: @@ -155,8 +155,7 @@ public: public: constexpr char at(size_t pos) const noexcept { - assert (pos < map_.size()); - return map_[pos]; + return X_ASSERT(pos < map_.size()), map_[pos]; } private: diff --git a/include/jwt/config.hpp b/include/jwt/config.hpp new file mode 100644 index 0000000..6370510 --- /dev/null +++ b/include/jwt/config.hpp @@ -0,0 +1,51 @@ +/* + Copyright (c) 2018 Arun Muralidharan + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ +#ifndef CPP_JWT_CONFIG_HPP +#define CPP_JWT_CONFIG_HPP + +#ifdef _MSC_VER +#define strncasecmp _strnicmp +#define strcasecmp _stricmp +#endif + +// To hack around Visual Studio error: +// error C3431: 'algorithm': a scoped enumeration cannot be redeclared as an unscoped enumeration +#ifdef _MSC_VER +#define SCOPED_ENUM enum class +#else +#define SCOPED_ENUM enum +#endif + +// To hack around Visual Studio error +// error C3249: illegal statement or sub-expression for 'constexpr' function +// Doesn't allow assert to be part of constexpr functions. +// Copied the solution as described in: +// https://akrzemi1.wordpress.com/2017/05/18/asserts-in-constexpr-functions/ +#if defined NDEBUG +# define X_ASSERT(CHECK) void(0) +#else +# define X_ASSERT(CHECK) \ + ( (CHECK) ? void(0) : []{assert(!#CHECK);}() ) +#endif + + +#endif diff --git a/include/jwt/impl/jwt.ipp b/include/jwt/impl/jwt.ipp index bfd36d1..8e3649b 100644 --- a/include/jwt/impl/jwt.ipp +++ b/include/jwt/impl/jwt.ipp @@ -23,6 +23,7 @@ SOFTWARE. #ifndef JWT_IPP #define JWT_IPP +#include "jwt/config.hpp" #include "jwt/detail/meta.hpp" #include diff --git a/include/jwt/jwt.hpp b/include/jwt/jwt.hpp index b6dae3d..76eacdd 100644 --- a/include/jwt/jwt.hpp +++ b/include/jwt/jwt.hpp @@ -32,6 +32,7 @@ SOFTWARE. #include #include "jwt/base64.hpp" +#include "jwt/config.hpp" #include "jwt/algorithm.hpp" #include "jwt/string_view.hpp" #include "jwt/parameters.hpp" @@ -75,7 +76,7 @@ inline enum type str_to_type(const jwt::string_view typ) noexcept * Converts an instance of type `enum class type` * to its string equivalent. */ -inline jwt::string_view type_to_str(enum type typ) +inline jwt::string_view type_to_str(SCOPED_ENUM type typ) { switch (typ) { case type::JWT: return "JWT"; @@ -112,7 +113,7 @@ enum class registered_claims * Converts an instance of type `enum class registered_claims` * to its string equivalent representation. */ -inline jwt::string_view reg_claims_to_str(enum registered_claims claim) noexcept +inline jwt::string_view reg_claims_to_str(SCOPED_ENUM registered_claims claim) noexcept { switch (claim) { case registered_claims::expiration: return "exp"; @@ -296,7 +297,7 @@ public: // 'tors * Constructor taking specified algorithm type * and JWT type. */ - jwt_header(enum algorithm alg, enum type typ = type::JWT) + jwt_header(SCOPED_ENUM algorithm alg, SCOPED_ENUM type typ = type::JWT) : alg_(alg) , typ_(typ) { @@ -326,7 +327,7 @@ public: // Exposed APIs /** * Set the algorithm. */ - void algo(enum algorithm alg) + void algo(SCOPED_ENUM algorithm alg) { alg_ = alg; payload_["alg"] = alg_to_str(alg_).to_string(); @@ -344,7 +345,7 @@ public: // Exposed APIs /** * Get the algorithm. */ - enum algorithm algo() const noexcept + SCOPED_ENUM algorithm algo() const noexcept { return alg_; } @@ -356,7 +357,7 @@ public: // Exposed APIs /** * Set the JWT type. */ - void typ(enum type typ) noexcept + void typ(SCOPED_ENUM type typ) noexcept { typ_ = typ; payload_["typ"] = type_to_str(typ_).to_string(); @@ -374,7 +375,7 @@ public: // Exposed APIs /** * Get the JWT type. */ - enum type typ() const noexcept + SCOPED_ENUM type typ() const noexcept { return typ_; } @@ -489,10 +490,10 @@ public: // Exposed APIs private: // Data members /// The Algorithm to use for signature creation - enum algorithm alg_ = algorithm::NONE; + SCOPED_ENUM algorithm alg_ = algorithm::NONE; /// The type of header - enum type typ_ = type::JWT; + SCOPED_ENUM type typ_ = type::JWT; // The JSON payload object json_t payload_; @@ -602,7 +603,7 @@ public: // Exposed APIs !std::is_same, system_time_t>::value || !std::is_same, jwt::string_view>::value >> - bool add_claim(enum registered_claims cname, T&& cvalue, bool overwrite=false) + bool add_claim(SCOPED_ENUM registered_claims cname, T&& cvalue, bool overwrite=false) { return add_claim( reg_claims_to_str(cname), @@ -616,7 +617,7 @@ public: // Exposed APIs * This overload takes `registered_claims` as the claim name and * `system_time_t` as the claim value type. */ - bool add_claim(enum registered_claims cname, system_time_t tp, bool overwrite=false) + bool add_claim(SCOPED_ENUM registered_claims cname, system_time_t tp, bool overwrite=false) { return add_claim( reg_claims_to_str(cname), @@ -631,7 +632,7 @@ public: // Exposed APIs * This overload takes `registered_claims` as the claim name and * `jwt::string_view` as the claim value type. */ - bool add_claim(enum registered_claims cname, jwt::string_view cvalue, bool overwrite=false) + bool add_claim(SCOPED_ENUM registered_claims cname, jwt::string_view cvalue, bool overwrite=false) { return add_claim( reg_claims_to_str(cname), @@ -664,7 +665,7 @@ public: // Exposed APIs * JSON library will throw an exception. */ template - decltype(auto) get_claim_value(enum registered_claims cname) const + decltype(auto) get_claim_value(SCOPED_ENUM registered_claims cname) const { return get_claim_value(reg_claims_to_str(cname)); } @@ -688,7 +689,7 @@ public: // Exposed APIs * Overload which takes the claim name as an instance * of `registered_claims` type. */ - bool remove_claim(enum registered_claims cname) + bool remove_claim(SCOPED_ENUM registered_claims cname) { return remove_claim(reg_claims_to_str(cname)); } @@ -712,7 +713,7 @@ public: // Exposed APIs * Overload which takes the claim name as an instance * of `registered_claims` type. */ - bool has_claim(enum registered_claims cname) const noexcept + bool has_claim(SCOPED_ENUM registered_claims cname) const noexcept { return has_claim(reg_claims_to_str(cname)); } @@ -737,7 +738,7 @@ public: // Exposed APIs * type `registered_claims`. */ template - bool has_claim_with_value(const enum registered_claims cname, T&& value) const + bool has_claim_with_value(const SCOPED_ENUM registered_claims cname, T&& value) const { return has_claim_with_value(reg_claims_to_str(cname), std::forward(value)); } @@ -1014,7 +1015,7 @@ public: // Exposed APIs * @note: See `jwt_payload::add_claim` for more details. */ template - jwt_object& add_claim(enum registered_claims cname, T&& value) + jwt_object& add_claim(SCOPED_ENUM registered_claims cname, T&& value) { return add_claim(reg_claims_to_str(cname), std::forward(value)); } @@ -1031,7 +1032,7 @@ public: // Exposed APIs * * @note: See `jwt_payload::remove_claim` for more details. */ - jwt_object& remove_claim(enum registered_claims cname) + jwt_object& remove_claim(SCOPED_ENUM registered_claims cname) { return remove_claim(reg_claims_to_str(cname)); } @@ -1053,7 +1054,7 @@ public: // Exposed APIs * * @note: See `jwt_payload::has_claim` for more details. */ - bool has_claim(enum registered_claims cname) const noexcept + bool has_claim(SCOPED_ENUM registered_claims cname) const noexcept { return payload().has_claim(cname); }