stdcxx-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Travis Vitek" <tvi...@quovadx.com>
Subject RE: [PATCH] Add overflow checking to basic_string append and push_back
Date Thu, 20 Sep 2007 22:34:39 GMT
 

Martin,

I think that you are right in the case of push_back, or when the string
to append is short. My last testcase didn't prove anything. This one
does. If you use the current trunk, this prints '4 aaaa' to the console.
i.e. appending 20 characters to a buffer with 240 should not get you 4,
should it?

Travis


#include <string>
#include <stdexcept>
#include <malloc.h>

template <class _TypeT> class
Xallocator;

template <>
class Xallocator<void>
{
public:
    typedef void              value_type;
    typedef value_type*       pointer;
    typedef const value_type* const_pointer;
   
    template <class _TypeU> 
    struct rebind {
        typedef Xallocator<_TypeU> other;
    };    
};

template <class _TypeT>
class Xallocator
{
public:
    typedef unsigned char       size_type;
    typedef signed char         difference_type;
    typedef _TypeT              value_type;
    typedef value_type*         pointer;
    typedef const value_type*   const_pointer;
    typedef value_type&         reference;
    typedef const value_type&   const_reference;

    Xallocator () {
    }

    Xallocator (const Xallocator &) {
    }

    template <class _TypeU> 
    struct rebind {
        typedef Xallocator<_TypeU> other;
    };

    template <class _TypeU>
    Xallocator (const Xallocator<_TypeU>&) {
    }

    template <class _TypeU>
    Xallocator&
    operator= (const Xallocator<_TypeU>&) { 
        return *this; 
    }

    pointer address (reference __x) const {
        return _RWSTD_REINTERPRET_CAST (pointer,
                   &_RWSTD_REINTERPRET_CAST (char&, __x));
    }

    const_pointer address (const_reference __x) const {
        return _RWSTD_REINTERPRET_CAST (const_pointer,
                   &_RWSTD_REINTERPRET_CAST (const char&, __x));
    }

    pointer allocate (size_type __n, Xallocator<void>::const_pointer =
0) {
        return (pointer)::malloc(__n * sizeof (value_type));
    }

    void deallocate (pointer __p, size_type) {
        ::free(__p);
    }

    // 20.4.1.1, p11 - the largest N for which allocate (N) might
succeed
    size_type max_size () const { 
        return 255;
    }

    void construct (pointer __p, const_reference __val) {
        new (__p) value_type(__val);
    }
    
    void destroy (pointer __p) {
        __p->~_TypeT ();
    }
};

typedef std::basic_string<char, std::char_traits<char>, Xallocator<char>
> String;

#include <stdio.h>

int main()
{
    int failed = 0;

    try {
        String a (240, 'a');
        String b (240, 'b');

        // ensure that we will overflow
        assert (a.max_size () < a.size () + 20);

        a.append (b.c_str(), 20);

        printf ("%u %s\n", a.size (), a.c_str ());

        failed += 1;
    }
    catch (const std::length_error&) {
        // should throw
    }
    catch (...) {
        failed += 1;
    }

    return failed;
}

Mime
View raw message