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 — Let's get rid of sprintf() · Issue #101703 · python/cpython

Let's get rid of sprintf() #101703

New issue
Copy link
New issue
Copy link
Open
Open
Let's get rid of sprintf()#101703
Copy link
Labels
type-refactorCode refactoring (with no changes in behavior)Code refactoring (with no changes in behavior)

Description

@gvanrossum
gvanrossum
opened on Feb 8, 2023
Issue body actions

On macOS with Xcode 14 we now get warnings like these:

Objects/unicodeobject.c:736:16: warning: 'sprintf' is deprecated: This function is provided for compatibility reasons only.  Due to security concerns inherent in the design of sprintf(3), it is highly recommended that you use snprintf(3) instead. [-Wdeprecated-declarations]

While we can prove to ourselves that these specific sprintf() calls are safe, the warnings are annoying, but disabling them would also disable other, more useful warnings (or so @Yhg1s tells me on Discord). So let's just switch these to snprintf().

Linked PRs

  • gh-101703: use PyOS_snprintf instead of sprintf #101729
  • gh-101703: Use PyOS_snprintf in _freeze_module #161871
Reacted by Erlend E. Aasland, Oleg Iarygin, Furkan Onder, Christopher Chavez and Suraj
Reacted by Erlend E. Aasland and Furkan Onder

Activity

  1. gvanrossum
    added
    type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
    on Feb 8, 2023
  2. terryjreedy commented on Feb 8, 2023

    @terryjreedy
    terryjreedy
    on Feb 8, 2023
    Member
    More actions

    There are 49 hits in our .c code + some in externals.

  3. sobolevn
    added 2 commits that reference this issue on Feb 9, 2023

    pythongh-101703: use `snprintf` instead of `sprintf`

    38f8e7d

    pythongh-101703: use `snprintf` instead of `sprintf`

    b33fb2d
  4. serhiy-storchaka commented on Feb 9, 2023

    @serhiy-storchaka
    serhiy-storchaka
    on Feb 9, 2023
    Member
    More actions

    Interesting, there were issues with portability of snprintf (on Windows) in the past. I hope they were fixed in last 20 years.

  5. erlend-aasland commented on Feb 9, 2023

    @erlend-aasland
    erlend-aasland
    on Feb 9, 2023
    Contributor
    More actions

    Interesting, there were issues with portability of snprintf (on Windows) in the past. I hope they were fixed in last 20 years.

    CC. @eryksun

  6. eryksun commented on Feb 9, 2023

    @eryksun
    eryksun
    on Feb 9, 2023
    Contributor
    More actions

    Supported builds of Python 3.5+ on Windows use Visual Studio 2015+ and the Universal C Runtime (UCRT), for which snprintf() and vsnprintf() conform to C99. In Python 3.9+, "Include/pyerrors.h" no longer defines these two functions as macros that call non-standard _snprintf() and _vsnprintf().

    PyOS_vsnprintf() in "Python/mysnprintf.c" was apparently overlooked when "pyerrors.h" was updated. It should have been modified to always call vsnprintf(). Also, all PyOS_snprintf() and PyOS_vsnprintf() calls can be replaced with snprintf() and vsnprintf().

    Reacted by Erlend E. Aasland and Suraj
  7. terryjreedy commented on Apr 24, 2023

    @terryjreedy
    terryjreedy
    on Apr 24, 2023
    Member
    More actions

    I closed #103733 as duplicate of this.

  8. gvanrossum commented on Mar 19, 2024

    @gvanrossum
    gvanrossum
    on Mar 19, 2024
    MemberAuthor
    More actions

    @terryjreedy @sobolevn Can this be closed? I haven't seen those warnings in a while, though I see plenty of sprintf() calls in the code still.

  9. terryjreedy commented on Mar 20, 2024

    @terryjreedy
    terryjreedy
    on Mar 20, 2024
    Member
    More actions

    I have no involvement with C code, so fine with me. @serhiy-storchaka ?

  10. sobolevn commented on Mar 20, 2024

    @sobolevn
    sobolevn
    on Mar 20, 2024
    Member
    More actions

    I've tried to compile CPython with explicit -Wdeprecated-declarations set in PY_STDMODULE_CFLAGS and got no warnings. However, sprintf() is still widely used:

    » ag 'sprintf\('  
    Misc/HISTORY
    24555:  the standard sprintf() and vsprintf() C lib APIs, these versions
    33626:similar to sprintf() in C.  The right argument is either a single
    33627:value or a tuple of values.  All features of Standard C sprintf() are
    
    Python/flowgraph.c
    276:        sprintf(arg, "arg: %d ", i->i_oparg);
    279:        sprintf(arg, "target: %p [%d] ", i->i_target, i->i_oparg);
    
    Python/pystrtod.c
    1204:        exp_len = sprintf(p, "%+.02d", exp);
    
    Python/specialize.c
    368:        sprintf(buf, "%s%s.txt", dirname, hex_name);
    
    Objects/typeobject.c
    5591:        sprintf(msg, "type_traverse() called on non-heap type '%.100s'",
    
    Objects/unicodeobject.c
    789:        size = sprintf(str, "&#%d;", PyUnicode_READ(kind, data, i));
    2596:                    sprintf(buffer, fmt, va_arg(*vargs, long)) :
    2597:                    sprintf(buffer, fmt, va_arg(*vargs, unsigned long));
    2601:                    sprintf(buffer, fmt, va_arg(*vargs, long long)) :
    2602:                    sprintf(buffer, fmt, va_arg(*vargs, unsigned long long));
    2606:                    sprintf(buffer, fmt, va_arg(*vargs, Py_ssize_t)) :
    2607:                    sprintf(buffer, fmt, va_arg(*vargs, size_t));
    2610:                len = sprintf(buffer, fmt, va_arg(*vargs, ptrdiff_t));
    2614:                    sprintf(buffer, fmt, va_arg(*vargs, intmax_t)) :
    2615:                    sprintf(buffer, fmt, va_arg(*vargs, uintmax_t));
    2619:                    sprintf(buffer, fmt, va_arg(*vargs, int)) :
    2620:                    sprintf(buffer, fmt, va_arg(*vargs, unsigned int));
    2672:        len = sprintf(number, "%p", va_arg(*vargs, void*));
    8358:            sprintf(buffer, "&#%d;", (int)PyUnicode_READ_CHAR(unicode, collpos));
    
    Objects/bytesobject.c
    269:                sprintf(buffer, "%ld", va_arg(vargs, long));
    272:                sprintf(buffer, "%zd", va_arg(vargs, Py_ssize_t));
    275:                sprintf(buffer, "%d", va_arg(vargs, int));
    283:                sprintf(buffer, "%lu", va_arg(vargs, unsigned long));
    286:                sprintf(buffer, "%zu", va_arg(vargs, size_t));
    289:                sprintf(buffer, "%u", va_arg(vargs, unsigned int));
    296:            sprintf(buffer, "%i", va_arg(vargs, int));
    302:            sprintf(buffer, "%x", va_arg(vargs, int));
    328:            sprintf(buffer, "%p", va_arg(vargs, void*));
    564:/* fmt%(v1,v2,...) is roughly equivalent to sprintf(fmt, v1, v2, ...) */
    
    Parser/string_parser.c
    134:                sprintf(p, "\\U%08x", chr);
    
    Programs/_freeze_module.c
    124:    sprintf(filename, "<frozen %s>", name);
    
    Modules/_testexternalinspection.c
    234:    sprintf(maps_file_path, "/proc/%d/maps", pid);
    
    Modules/_pickle.c
    2110:            sprintf(pdata, "%c%ld\n", INT,  val);
    
    Modules/unicodedata.c
    1329:        sprintf(buffer, "CJK UNIFIED IDEOGRAPH-%X", code);
    
    Modules/_testcapimodule.c
    991:        sprintf(buffer, "%s module: \"%s\" attribute: \"%s\"", \
    
    Modules/getnameinfo.c
    142:        sprintf(numserv, "%d", ntohs(port));
    
    Modules/_datetimemodule.c
    1629:        sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
    1631:        sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
    1633:        sprintf(freplacement, "%06d", 0);
    
    Modules/_ctypes/stgdict.c
    651:            sprintf(buf, "%s:%s:", fieldfmt, fieldname);
    
    Modules/_ctypes/_ctypes.c
    398:                sprintf(buf, "%zd,", shape[k]);
    400:                sprintf(buf, "%zd)", shape[k]);
    2538:    cp += sprintf(cp, "%x", Py_SAFE_DOWNCAST(index, Py_ssize_t, int));
    2547:        cp += sprintf(cp, ":%x", Py_SAFE_DOWNCAST(target->b_index, Py_ssize_t, int));
    3269:        sprintf(mangled_name, "_%s@%d", name, i*4);
    4768:    sprintf(name, "%.200s_Array_%Id",
    4771:    sprintf(name, "%.200s_Array_%ld",
    
    

    Not sure why this warning is gone.

  11. erlend-aasland commented on Mar 20, 2024

    @erlend-aasland
    erlend-aasland
    on Mar 20, 2024
    Contributor
    More actions

    Well, we risk that when the next version your toolchain of choice is updated, the warnings will reappear. IMO we might as well fix them. @sobolevn's PR was a good start, but only needed to be split in more manageable chunks.

    Reacted by Eric V. Smith
  12. sobolevn commented on Mar 20, 2024

    @sobolevn
    sobolevn
    on Mar 20, 2024
    Member
    More actions

    I can redo some parts of it, there were rather easy. I'll start with them today.

  13. sobolevn commented on Nov 12, 2026

    @sobolevn
    sobolevn
    on Nov 12, 2026
    Member
    More actions

    Today I got this warning during CPython compilation:

    Programs/_freeze_module.c:129:5: warning: 'sprintf' is deprecated: This function is provided for compatibility reasons only.  Due to security concerns inherent in the design of sprintf(3), it is highly recommended that you use snprintf(3) instead. [-Wdeprecated-declarations]
      129 |     sprintf(filename, "<frozen %s>", name);
          |     ^
    /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/_stdio.h:278:1: note: 'sprintf' has been explicitly marked deprecated here
      278 | __deprecated_msg("This function is provided for compatibility reasons only.  Due to security concerns inherent in the design of sprintf(3), it is highly recommended that you use snprintf(3) instead.")
          | ^
    /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/cdefs.h:227:48: note: expanded from macro '__deprecated_msg'
      227 |         #define __deprecated_msg(_msg) __attribute__((__deprecated__(_msg)))
          |                                                       ^
    1 warning generated.
    

    Since my last big PR never made it in, I propose splitting the work into simple small PRs that are easy to review / merge / backport.

  14. sobolevn
    added
    type-refactorCode refactoring (with no changes in behavior)Code refactoring (with no changes in behavior)
    and removed
    type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
    on Nov 12, 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

    type-refactorCode refactoring (with no changes in behavior)Code refactoring (with no changes in behavior)

    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.