Skip to content

curses: in_wch()/in_wchstr()/getbkgrnd() can return garbage text with curses libraries that don't NUL-terminate cchar_t #152503

Description

@serhiy-storchaka

window.in_wch(), window.in_wchstr() and window.getbkgrnd() can return a complexchar whose text is garbage, usually surfacing as ValueError: character U+xxxxxxxx is not in range [U+0000; U+10ffff], when curses is built against a curses library whose cell-read functions don't NUL-terminate the cchar_t text array.

The module reads a cell into an uninitialized cchar_t (e.g. win_wch(win, &wcval)) then extracts the text with getcchar(). This relies on two behaviours ncurses happens to provide but X/Open doesn't require: that the read leaves the text array NUL-terminated, and that getcchar() writes the output text for an empty cell. NetBSD curses does neither — its read functions assume the caller zeroed the struct, and its getcchar() finds the text by scanning for L'\0' and writes nothing for an empty cell — so uninitialized bytes get interpreted as wide characters.

This doesn't reproduce on a stock ncursesw build; it's a latent bug that manifests with other backends (found testing against NetBSD curses), but the assumption is worth not depending on.

Fix:

  • Zero-initialize the cell buffers before the read: in_wch/getbkgrnd (curses_cell_t wcval = {0};) and in_wchstr (PyMem_NewPyMem_Calloc).
  • Default the getcchar() output to an empty string in the curses_getcchar() wrapper (wstr[0] = L'\0';), since getcchar() need not write the text of an empty cell.

Both are no-ops on ncurses; test_curses keeps passing and stays refleak-clean.

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    extension-modulesC modules in the Modules dirtype-bugAn unexpected behavior, bug, or error
    No fields configured for issues without a type.

    Projects

    Status
    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions