Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

format_to_n will hang infinitely if buffer size is < required size of formatted string. #1996

Closed
slicer4ever opened this issue Nov 8, 2020 · 1 comment

Comments

@slicer4ever
Copy link

slicer4ever commented Nov 8, 2020

Doing:

char Buffer[4];
fmt::format_to_n(Buffer, 4, "{}", "ABCDE")

will hang infinitely as the code here:

void buffer<T>::append(const U* begin, const U* end) {

void buffer<T>::append(const U* begin, const U* end) {
  do {
    auto count = to_unsigned(end - begin);
    try_reserve(size_ + count);
    auto free_cap = capacity_ - size_;
    if (free_cap < count) count = free_cap;
    std::uninitialized_copy_n(begin, count, make_checked(ptr_ + size_, count));
    size_ += count;
    begin += count;
  } while (begin != end);
}

Since try_reserve can not increase the capacity being a fixed size buffer, the free_cap will always be 0, and the program hangs due to this issue.

void buffer<T>::append(const U* begin, const U* end) {
  do {
    auto count = to_unsigned(end - begin);
    try_reserve(size_ + count);
    auto free_cap = capacity_ - size_;
    if(free_cap) {
        if (free_cap < count) count = free_cap;
        std::uninitialized_copy_n(begin, count, make_checked(ptr_ + size_, count));
    }
    size_ += count;
    begin += count;
  } while (begin != end);
}

Adding a check that free_cap is not 0 before we truncate count, and copy means that format_to_n will still report the needed buffer size to contain the string. this is consistent with behavior such as:

char Buffer[4];
fmt::format_to_n(Buffer, 4, 10000);

where Size of the result of format_to_n will report 5 even though it filled buffer with '1000'.

I'm unsure if free_cap can temporarily be 0 in some instances, in which case an alternative check may need to be performed that we are working on a fixed sized buffer.

@vitaut
Copy link
Contributor

vitaut commented Nov 8, 2020

Good catch, thanks! Fixed in 5bedcb6.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants