Skip to content

Failed to compile while using custom allocators #295

Open
@josephofthebread

Description

@josephofthebread

What happened?

Hey, I am implementing JWT authorization for my http server.
My server uses custom allocator and custom memory management system, since on Apple silicon there are not many tools for profiling. I am using nlohmann json implementation. Compilation fails with the following error message:

In file included from private/verification/authenticator.cpp:2:
In file included from public/verification/jwt.hpp:14:
dep/jwt/include/jwt-cpp/jwt.h:2852:45: error: no matching function for call to 'encode'
                                        return base::trim<alphabet::base64url>(base::encode<alphabet::base64url>(data));
                                                                               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dep/jwt/include/jwt-cpp/jwt.h:2804:15: note: in instantiation of function template specialization 'jwt::builder<css::JwtJsonTraits>::sign<jwt::algorithm::hs256>' requested here
                        auto res = sign(algo, ec);
                                   ^
private/verification/authenticator.cpp:20:26: note: in instantiation of function template specialization 'jwt::builder<css::JwtJsonTraits>::sign<jwt::algorithm::hs256>' requested here
                        .sign(jwt::algorithm::hs256(m_Manager->getAccessTokenKey().c_str()));
                         ^
dep/jwt/include/jwt-cpp/base.h:252:15: note: candidate function template not viable: no known conversion from 'const basic_string<[2 * ...], Allocator<char, MemoryTag::STRING>>' to 'const basic_string<[2 * ...], allocator<char>>' for 1st argument
                std::string encode(const std::string& bin) {

What I am considering to be going on is that there is no specialization for base::encode to take std::string with custom allocator (code):

return sign(
algo,
[](const typename json_traits::string_type& data) {
	return base::trim<alphabet::base64url>(base::encode<alphabet::base64url>(data));
},
ec);

Compiler version: Apple clang version 14.0.3 (clang-1403.0.22.14.1)
Compilation options: -Wno-missing-braces -Wdouble-promotion -Wsign-conversion -Wunused-variable --std=c++20 -glldb

How To Reproduce?

Code:

String generateToken() {
        return jwt::create<JwtJsonTraits>()
                .set_issuer(CS_VERSION_STRING)
                .set_type("JWS")
                .set_payload_claim("type", "refresh")
                .set_payload_claim("username", username)
                .set_payload_claim("passwordHash", passwordHash)
                
                // "m_Manager->getRefreshTokenKey()"" returns String with native allocator
                // There .c_str is being called to convert string with native allocator
                // to std::string, because jwt::algorithm::hs256 accepts only std::string
                .sign(jwt::algorithm::hs256(m_Manager->getRefreshTokenKey().c_str()));
}

Json traits:

struct JwtJsonTraits
{
        using value_type        = Json;
        using object_type       = JsonObject;
        using array_type        = JsonArray;
        using string_type       = String;
        using number_type       = Json::number_float_t;
        using integer_type      = Json::number_integer_t;
        using boolean_type      = Json::boolean_t;

        static jwt::json::type get_type(const value_type &value)
        {
                using jwt_type = jwt::json::type;

                switch (value.type())
                {
                case nlohmann::detail::value_t::object:
                        return jwt_type::object;
                case nlohmann::detail::value_t::array:
                        return jwt_type::array;
                case nlohmann::detail::value_t::string:
                        return jwt_type::string;
                case nlohmann::detail::value_t::boolean:
                        return jwt_type::boolean;
                case nlohmann::detail::value_t::number_integer:
                        return jwt_type::number;
                case nlohmann::detail::value_t::null:
                case nlohmann::detail::value_t::number_unsigned:
                case nlohmann::detail::value_t::number_float:
                case nlohmann::detail::value_t::binary:
                case nlohmann::detail::value_t::discarded:
                        break;
                };

                throw std::invalid_argument("invalid json value type");
        }

        static object_type as_object(const value_type &val) { return val.get<object_type>(); }
        static array_type as_array(const value_type &val) { return val.get<array_type>(); }
        static string_type as_string(const value_type &val) { return val.get<string_type>(); }
        static number_type as_number(const value_type &val) { return val.get<number_type>(); }
        static integer_type as_integer(const value_type &val) { return val.get<integer_type>(); }
        static boolean_type as_boolean(const value_type &val) { return val.get<boolean_type>(); }

        static bool parse(value_type &val, string_type source) { return (val = jsonParse(std::move(source)), true); }
        static string_type serialize(const value_type &val) { return val.dump(); }
}

Aliases

template<class CharT>
using BasicString = std::basic_string<CharT, std::char_traits<CharT>, Allocator<CharT, MemoryTag::STRING>>;
using String = BasicString<char>;

template<class Type>
using JsonAllocator = Allocator<Type, MemoryTag::JSON>;
using Json = nlohmann::basic_json<std::map, std::vector, String, bool, int64_t, uint64_t, double, JsonAllocator>;

Version

0.6.0

What OS are you seeing the problem on?

MacOS

What compiler are you seeing the problem on?

Clang

Relevant log output

No response

Code of Conduct

  • I agree to follow this project's Code of Conduct

Metadata

Metadata

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions