Skip to content

_csv: _set_str() missing NULL check after PyUnicode_DecodeASCII() #145978

@raminfp

Description

@raminfp

Bug report

Bug description:

In Modules/_csv.c, _set_str() does not check the return value of PyUnicode_DecodeASCII() when using the default value. If the allocation fails (OOM), *target is set to NULL and the function returns 0 (success).

https://github.com/python/cpython/blob/main/Modules/_csv.c#L315-L329

static int
_set_str(const char *name, PyObject **target, PyObject *src, const char *dflt)
{
    if (src == NULL)
        *target = PyUnicode_DecodeASCII(dflt, strlen(dflt), NULL);
        // ^^^ no NULL check 
    else {
        ...
    }
    return 0; // Returns 0 even if allocation failed
}

This function is called for lineterminator:

DIASET(_set_str, "lineterminator", &self->lineterminator, lineterminator, "\r\n");

If allocation fails, self->lineterminator is NULL. Subsequent calls to PyUnicode_GET_LENGTH(dialect->lineterminator) (e.g. in join_append_data at line 1183 or join_append_lineterminator at line 1299) will dereference NULL.

Fix

static int
_set_str(const char *name, PyObject **target, PyObject *src, const char *dflt)
{
    if (src == NULL) {
        *target = PyUnicode_DecodeASCII(dflt, strlen(dflt), NULL);
        if (*target == NULL)
            return -1;
    }
    else {
        if (!PyUnicode_Check(src)) {
            PyErr_Format(PyExc_TypeError,
                         "\"%s\" must be a string, not %T", name, src);
            return -1;
        }
        Py_XSETREF(*target, Py_NewRef(src));
    }
    return 0;
}

CPython versions tested on:

CPython main branch

Operating systems tested on:

Linux

Metadata

Metadata

Assignees

No one assigned

    Labels

    extension-modulesC modules in the Modules dirtype-bugAn unexpected behavior, bug, or error

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions