[Python-checkins] cpython (merge 3.2 -> default): Fix out of bounds read in long_new() for empty bytes with an explicit base.

Stefan Krah stefan at bytereef.org
Wed Sep 12 16:00:03 CEST 2012


christian.heimes <python-checkins at python.org> wrote:
>   Fix out of bounds read in long_new() for empty bytes with an explicit base. int(b'', somebase) calls PyLong_FromString() with char* of length 1 but the function accesses the first argument at offset 1. CID 715359
> 
> files:
>   Objects/longobject.c |  4 ++--
>   1 files changed, 2 insertions(+), 2 deletions(-)
> 
> 
> diff --git a/Objects/longobject.c b/Objects/longobject.c
> --- a/Objects/longobject.c
> +++ b/Objects/longobject.c
> @@ -4285,8 +4285,8 @@
>              string = PyByteArray_AS_STRING(x);
>          else
>              string = PyBytes_AS_STRING(x);
> -        if (strlen(string) != (size_t)size) {
> -            /* We only see this if there's a null byte in x,
> +        if (strlen(string) != (size_t)size || !size) {
> +            /* We only see this if there's a null byte in x or x is empty,
>                 x is a bytes or buffer, *and* a base is given. */
>              PyErr_Format(PyExc_ValueError,
>                           "invalid literal for int() with base %d: %R",



This is a false positive: 

    Assumption: string == ""

    Call:  PyLong_FromString("", NULL, (int)base);

        Now: str == ""

        Coverity claims an invalid access at str[1]:

            if (str[0] == '0' &&
                ((base == 16 && (str[1] == 'x' || str[1] == 'X')) ||
                (base == 8  && (str[1] == 'o' || str[1] == 'O')) ||
                (base == 2  && (str[1] == 'b' || str[1] == 'B'))))

        But str[1] is never accessed due to shortcut evaluation.


Coverity appears to have serious problems with shortcut evaluations in many
places.


Stefan Krah




More information about the Python-checkins mailing list