Skip to content

Commit 858b05c

Browse files
Fix TSA #2816217: suppress Flawfinder false positive on Cython JoinPyUnicode memcpy (#2029)
* Fix TSA #2816217: suppress Flawfinder false positive on Cython JoinPyUnicode memcpy Flawfinder's buffer/memcpy rule (CWE-120) fires on any memcpy() call by default. The flagged call sits inside the Cython 3.x string-join helper __Pyx_PyUnicode_Join: memcpy((char *)result_udata + (char_pos << kind_shift), udata, (size_t) (ulength << kind_shift)); It is provably safe: * result_uval was just allocated via PyUnicode_New(result_ulength, max_char) and result_udata = PyUnicode_DATA(result_uval) points into that buffer. * The immediately preceding check (PY_SSIZE_T_MAX >> kind_shift) - ulength < char_pos guards against char_pos+ulength overflow before the memcpy executes. * result_ulength is computed by the caller as the sum of input lengths, so char_pos + ulength <= result_ulength after each iteration. The byte count `ulength << kind_shift` is bounded by the allocated buffer. Add an inline /* Flawfinder: ignore */ annotation on the flagged line in the Cython-generated _pydevd_sys_monitoring_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> * Fix SyntaxError: add missing closing paren on JoinPyUnicode .replace() call The merge from main inadvertently dropped the closing ')' of the new JoinPyUnicode '.replace(...)' call, so the subsequent 'read<end' '.replace(...)' block was being parsed as continued arguments. Add the missing ')' (and a blank line) to separate the two calls cleanly. --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent f0c34f1 commit 858b05c

2 files changed

Lines changed: 12 additions & 1 deletion

File tree

src/debugpy/_vendored/pydevd/_pydevd_sys_monitoring/_pydevd_sys_monitoring_cython.c

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/debugpy/_vendored/pydevd/setup_pydevd_cython.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,17 @@ def build_extension(dir_name, extension_name, target_pydevd_name, force_cython,
177177
c_file_contents = c_file_contents.replace(r"_pydevd_bundle\\pydevd_cython.pxd", "_pydevd_bundle/pydevd_cython.pxd")
178178
c_file_contents = c_file_contents.replace(r"_pydevd_bundle\\pydevd_cython.pyx", "_pydevd_bundle/pydevd_cython.pyx")
179179

180+
# Suppress Flawfinder false positive (CWE-120) in the Cython 3.x
181+
# `__Pyx_PyUnicode_Join` boilerplate: the destination `result_uval` was just
182+
# allocated via `PyUnicode_New(result_ulength, max_char)`, and the immediately
183+
# preceding `(PY_SSIZE_T_MAX >> kind_shift) - ulength < char_pos` check guards
184+
# against char_pos+ulength overflow before the memcpy. The size argument is
185+
# `ulength << kind_shift` which is bounded by the pre-allocated buffer length.
186+
c_file_contents = c_file_contents.replace(
187+
" memcpy((char *)result_udata + (char_pos << kind_shift), udata, (size_t) (ulength << kind_shift));\n",
188+
" memcpy((char *)result_udata + (char_pos << kind_shift), udata, (size_t) (ulength << kind_shift)); /* Flawfinder: ignore */\n",
189+
)
190+
180191
# Suppress Flawfinder false positive (CWE-120) in the Cython 3.x
181192
# CIntToPyUnicode boilerplate (`__Pyx____Pyx_PyUnicode_From_int`): the destination
182193
# `dpos` is a stack buffer of size `sizeof(int)*3+2`, and `dpos -= 2` immediately

0 commit comments

Comments
 (0)