Fix TSA #2816216: suppress Flawfinder false positive on Cython DIGIT_PAIRS_8 memcpy#2028
Merged
StellaHuang95 merged 3 commits intoMay 29, 2026
Conversation
…PAIRS_8 memcpy
Flawfinder's buffer/memcpy rule (CWE-120) fires on any memcpy() call by
default. The flagged call sits inside the Cython 3.x integer formatter
__Pyx____Pyx_PyUnicode_From_int (case 'o'):
memcpy(dpos, DIGIT_PAIRS_8 + digit_pos * 2, 2);
It is provably safe:
* dpos points into the stack buffer `digits[sizeof(int)*3+2]` (14 bytes
for a 32-bit int); `dpos -= 2` immediately precedes the copy and the
enclosing do/while loop iterates at most ceil(log_64(max_int)) times,
so dpos always stays >= digits.
* DIGIT_PAIRS_8 is a 128-byte compile-time constant table containing the
64 two-character octal digit pairs "00".."77". `digit_pos = abs(remaining
% 64)`, so `digit_pos * 2` ranges over [0, 126] and reads 2 bytes from
offset [0, 127] -- within the table.
* The size argument is the compile-time constant 2.
Add an inline /* Flawfinder: ignore */ annotation on the flagged line in
the Cython-generated pydevd_cython.c and extend the existing
post-processing block in setup_pydevd_cython.py so the annotation is
re-applied automatically whenever Cython regenerates the .c files.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
rchiodo
approved these changes
May 28, 2026
Contributor
rchiodo
left a comment
There was a problem hiding this comment.
Approved via Review Center.
…) call Same merge-from-main artifact as microsoft#2029: the closing ')' of the new DIGIT_PAIRS_8 '.replace(...)' call was dropped when the 'read<end' '.replace(...)' block was spliced in, leaving the second call's args being parsed as continued positional args to the first.
Contributor
Author
rchiodo
approved these changes
May 29, 2026
Contributor
rchiodo
left a comment
There was a problem hiding this comment.
Approved via Review Center.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Issue
Internal Flawfinder compliance scan flagged a
memcpyin the Cython-generatedpydevd_cython.c.FlawFinder/buffer/memcpy— "Does not check for buffer overflows when copying to destination (CWE-120)"src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_cython.cWhat Flawfinder reported
inside the Cython 3.x integer-to-string helper
__Pyx____Pyx_PyUnicode_From_int(case'o'of the format-char switch).Why this is a false positive
Flawfinder flags every
memcpy()call by default because it can't statically prove the size argument is safe. In this case all three arguments are provably bounded:char digits[sizeof(int)*3+2]. Each iteration doesdpos -= 2before the 2-byte copy, and the enclosingdo/whileloop dividesremainingby 64 each pass, so it iterates at most ⌈log₆₄(INT_MAX)⌉ times — well within the allocated buffer.DIGIT_PAIRS_8is a 128-byte compile-time constant table (64 pairs × 2 ASCII chars).digit_pos = abs(remaining % 64), so the offsetdigit_pos * 2is in[0, 126]— the 2-byte read is always inside the table.2. No way for it to be wrong.This is Cython runtime boilerplate that mirrors the same pattern used in CPython itself.
Fix
/* Flawfinder: ignore */to the flagged line. This is the documented Flawfinder suppression token (seeflawfinder --help).c_file_contents.replace(...)to the existing post-processing block insetup_pydevd_cython.pyso the suppression is automatically re-applied if Cython is re-run to regenerate the.cfile.The annotation is a C block comment — equivalent to whitespace at the lexer level, with zero effect on compiled output or runtime behavior.
Verification
Ran Flawfinder 2.0.20 locally against the modified file:
flawfinder --neverignore(suppressions disabled)The originally flagged warning is silenced, and the positive control with
--neverignoreconfirms the suppression is what's silencing it.Risk
Zero behavioral change. The
.cfile edit is a comment; thesetup_pydevd_cython.pyedit is astr.replace()that is a no-op if the matched text is absent (so it's safe even if Cython upstream changes its output).