off by one error

mail@pastecode.io avatar
unknown
c_cpp
12 days ago
1.8 kB
27
Indexable
Never
Result get_string(const XXX *xxxp,
                  const char *key,
                  size_t key_size,
                  char *out_str_buf,
                  size_t out_str_capacity)
{
    if (xxxp == nullptr || out_str_buf == nullptr || key == nullptr)
        return ERROR_RESULT(INVALID_ARGUMENT);

    // check the type is object
    const SharedBase *base = reinterpret_cast<const SharedBase *>(xxxp);
    const auto target_type = base->get_type();
    if (target_type != OBJECT)
        return ERROR_RESULT(INVALID_ARGUMENT);

    // Get the value associated with the given key.
    IOBuffer buffer;
    const Object *self = reinterpret_cast<const Object *>(xxxp);
    auto result = self->get_value(std::string(key, key_size), buffer);
    if (result.enum_result != SUCCESS)
        return result;

    // check if the target type is a string
    const auto *target_ptr = std::get_if<std::string>(&buffer);
    if (target_ptr == nullptr)
    {
        release(buffer);
        return ERROR_RESULT(TYPE_ERROR);
    }

    if (target_ptr->size() >= out_str_capacity)
    {
        // The reason to add 1 is to account for the null-terminator,
        // preventing the caller from using strlen related functions
        // by passing one more byte to the caller than the actual string size
        std::string msg = "The output buffer is not enough to store the string. The required size is ";
        msg += std::to_string(target_ptr->size());
        auto res_not_enough = Result(NOT_ENOUGH_MEMORY,
                                     msg,
                                     target_ptr->size() + 1);
        release(buffer);
        return res_not_enough;
    }

    std::copy(target_ptr->begin(), target_ptr->end(), out_str_buf);
    out_str_buf[target_ptr->size()] = '\0'; // null-terminator
    return Result(SUCCESS);
}
Leave a Comment