Travis Vitek wrote:
Martin Sebor wrote:
Travis Vitek wrote:
If that is the case, then why would we possibly need this same code in any of the other methods that are used to extend
the original string?
I don't think we do, really. I suspect the main reason why the
code is in all other (out-of-line) modifiers is so we can throw
the exception from function that is called directly by program
rather than from the one that happens to be called from it to
do the real work (all roads lead to replace()).


The problem I see is this...

I'm afraid this is my fault. I honestly didn't think about overflow
when I wrote the patch for push_back. I'm sorry if that caused
a problem! I'll try to to be more careful next time.

-- Mark


    // if you do this calculation without checking for overflow
    // you may be surprised when __size becomes smaller than
    // capacity. [240 + 20 = 6]
    //
    const size_type __size = size () + __n;

    // if we get here and capacity () is 240, but __size is 6
    // replace() won't be called.
    if (   capacity () <= __size
        || size_type (1) < size_type (_C_pref ()->_C_get_ref ()))
        return replace (size (), size_type (), __s, __n);

    // and we will copy past the end of _C_data
    traits_type::copy (_C_data + size (), __s, __n);

    // then throw a null terminator down
    traits_type::assign (_C_data [__size], value_type ());

    // and record the wrong size
    _C_pref ()->_C_size._C_size = __size;

With the default std::string/wstring, there isn't really a problem
because the allocator fails before size_type will overflow, but that
doesn't mean it isn't a problem.

Travis

I think the test case has some problems but I just saw your
update so I'll follow up on it there.

Martin



Reply via email to