GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Undefined Behavior in _PyUnicodeWriter_WriteASCIIString: NULL pointer passed to memcpy when len is 0 · Issue #146196 · python/cpython

Undefined Behavior in _PyUnicodeWriter_WriteASCIIString: NULL pointer passed to memcpy when len is 0 #146196

New issue
Copy link
New issue
Copy link
Closed
Closed
Undefined Behavior in _PyUnicodeWriter_WriteASCIIString: NULL pointer passed to memcpy when len is 0#146196
Copy link
Labels
interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

Description

@ashm-dev
ashm-dev
opened on Mar 20, 2026
Issue body actions

Bug report

Bug description:

The function _PyUnicodeWriter_WriteASCIIString in Objects/unicodeobject.c (or Objects/unicode_writer.c in some versions) contains a potential Undefined Behavior. When len is 0 and ascii is NULL, it calls memcpy with a NULL source pointer.

According to the C standard, passing NULL to memcpy is undefined even if the count is zero.

Proof of Concept

Clang's UndefinedBehaviorSanitizer (UBSan) reports:
../Objects/unicode_writer.c:494:36: runtime error: null pointer passed as argument 2, which is declared to never be null

This happens in the following block:

    case PyUnicode_1BYTE_KIND:
    {
        const Py_UCS1 *str = (const Py_UCS1 *)ascii;
        Py_UCS1 *data = writer->data;
        memcpy(data + writer->pos, str, len); // <--- UB if str is NULL and len is 0
        break;
    }

Mitigation

The function should return early if len == 0. This is a common pattern in CPython to avoid unnecessary work and prevent UB with memory functions.

    if (len == -1)
        len = strlen(ascii);
    if (len == 0)
        return 0;

CPython versions tested on:

CPython main branch

Operating systems tested on:

Linux

Linked PRs

  • gh-146196: Fix potential Undefined Behavior in _PyUnicodeWriter_WriteASCIIString #146201
  • [3.14] gh-146196: Fix Undefined Behavior in _PyUnicodeWriter_WriteASCIIString() (#146201) #146220

Activity

  1. ashm-dev
    added
    type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
    on Mar 20, 2026
  2. sergey-miryanov
    added
    interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)
    on Mar 20, 2026
  3. sergey-miryanov commented on Mar 20, 2026

    @sergey-miryanov
    sergey-miryanov
    on Mar 20, 2026
    Contributor
    More actions

    Could you check what versions affected and add MRE?

  4. ashm-dev commented on Mar 20, 2026

    @ashm-dev
    ashm-dev
    on Mar 20, 2026
    ContributorAuthor
    More actions

    This is only in the main branch, and I'll push a PR with the fix myself shortly

  5. ronaldoussoren commented on Mar 20, 2026

    @ronaldoussoren
    ronaldoussoren
    on Mar 20, 2026
    Contributor
    More actions

    Note that this will become valid code, see https://developers.redhat.com/articles/2024/12/11/making-memcpynull-null-0-well-defined#null_pointer_arithmetic. Both gcc and clang claim to conform this accepted proposal.

  6. ashm-dev commented on Mar 20, 2026

    @ashm-dev
    ashm-dev
    on Mar 20, 2026
    ContributorAuthor
    More actions

    @ronaldoussoren Am I the only one, C2y?
    I looked into that proposal (https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3322.pdf) too, BUT it’s for newer versions of C and will only be available in newer compilers. This problem is already relevant right now.

  7. ashm-dev
    added a commit that references this issue on Mar 20, 2026

    pythongh-146196: Fix potential Undefined Behavior in

    4da93eb
  8. vstinner commented on Mar 20, 2026

    @vstinner
    vstinner
    on Mar 20, 2026
    Member
    More actions

    Could you check what versions affected and add MRE?

    @serhiy-storchaka recently added writer.write_ascii(NULL, 0) test to Lib/test/test_capi/test_unicode.py. It should trigger the undefined behavior.

  9. vstinner commented on Mar 20, 2026

    @vstinner
    vstinner
    on Mar 20, 2026
    Member
    More actions

    Ah yes, I confirm that the newly added test triggers the undefined behavior:

    $ ./configure --with-pydebug --with-undefined-behavior-sanitizer
    $ make
    $ ./python -m test -v test_capi.test_unicode -m test_ascii
    (...)
    test_ascii (test.test_capi.test_unicode.PyUnicodeWriterTest.test_ascii) ...
    Objects/unicode_writer.c:494:9: runtime error: null pointer passed as argument 2, which is declared to never be null
    (...)
    

    So there is no need to add another test.

    The good news is that other PyUnicodeWriter functions don't emit undefined behavior (according to existing tests).

  10. serhiy-storchaka commented on Mar 20, 2026

    @serhiy-storchaka
    serhiy-storchaka
    on Mar 20, 2026
    Member
    More actions

    The test was backported to 3.14.

    Note that we get a crash for non-zero size. The case for zero size was not explicitly supported, the test was only added to prevent future regressions.

    We should ether make the behavior well defined by adding the explicit check for 0 size, or comment out the test. We can also explicitly raise SystemError for NULL. Either is fine. But since there is no use case for passing NULL, commenting out the test may be preferable -- it adds zero overhead.

  11. ashm-dev
    added 2 commits that reference this issue on Mar 20, 2026

    pythongh-146196: Fix potential Undefined Behavior in

    cd5ca81

    pythongh-146196: Fix potential Undefined Behavior in _PyUnicodeWriter…

    694c82a
  12. vstinner
    added 3 commits that reference this issue on Mar 20, 2026

    gh-146196: Fix Undefined Behavior in _PyUnicodeWriter_WriteASCIIStrin…

    cd10a2e

    pythongh-146196: Fix Undefined Behavior in _PyUnicodeWriter_WriteASCI…

    ca11535

    [3.14] gh-146196: Fix Undefined Behavior in _PyUnicodeWriter_WriteASC…

    6e73225
  13. vstinner commented on Mar 20, 2026

    @vstinner
    vstinner
    on Mar 20, 2026
    Member
    More actions

    I close the issue, it has been fixed.

    We should ether make the behavior well defined by adding the explicit check for 0 size, or comment out the test.

    I merged the PR #146201 which fixes the undefined behavior by adding if (len == 0) test.

    The test was backported to 3.14.

    I also backported the change fixing the undefined behavior to 3.14, so we should be good.

  14. vstinner
    closed this as completedon Mar 20, 2026
  15. CuriousLearner
    added a commit that references this issue on Mar 22, 2026

    Merge remote-tracking branch 'upstream/main' into fix-pythongh-138577

    2691ad9
  16. ljfp
    added a commit that references this issue on Apr 25, 2026

    pythongh-146196: Fix Undefined Behavior in _PyUnicodeWriter_WriteASCI…

    be90080
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

    interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.