Skip to content

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

Closed

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_New → PyMem_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

Activity

  1. added a commit that references this issue on Jun 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.16new features, bugs and security fixesextension-modulesC modules in the Modules dirtype-bugAn unexpected behavior, bug, or error

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions