diff options
author | colorfulappl <colorfulappl@qq.com> | 2022-12-20 10:20:42 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-12-20 10:20:42 (GMT) |
commit | 53063b7ffa8f8edf13dd7c81f89f034a3b3b71b6 (patch) | |
tree | 797882fdee0f73461e5c339ca86773d9c5028f4e /Tools | |
parent | b81d1c3be360c5f9a9dff0761e7f1f70a200f0aa (diff) | |
download | cpython-53063b7ffa8f8edf13dd7c81f89f034a3b3b71b6.zip cpython-53063b7ffa8f8edf13dd7c81f89f034a3b3b71b6.tar.gz cpython-53063b7ffa8f8edf13dd7c81f89f034a3b3b71b6.tar.bz2 |
[3.10] gh-99240: Fix double-free bug in Argument Clinic str_converter generated code (GH-99241) (#100353)
(cherry picked from commit 8dbe08eb7c807f484fe9870f5b7f5ae2881fd966)
Fix double-free bug mentioned at GH-99240, by moving memory clean up out of "exit" label.
Diffstat (limited to 'Tools')
-rwxr-xr-x | Tools/clinic/clinic.py | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index 1a59fa5..b0d1717 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -346,6 +346,12 @@ class CRenderData: # "goto exit" if there are any. self.return_conversion = [] + # The C statements required to do some operations + # after the end of parsing but before cleaning up. + # These operations may be, for example, memory deallocations which + # can only be done without any error happening during argument parsing. + self.post_parsing = [] + # The C statements required to clean up after the impl call. self.cleanup = [] @@ -751,6 +757,7 @@ class CLanguage(Language): {modifications} {return_value} = {c_basename}_impl({impl_arguments}); {return_conversion} + {post_parsing} {exit_label} {cleanup} @@ -1343,6 +1350,7 @@ class CLanguage(Language): template_dict['impl_parameters'] = ", ".join(data.impl_parameters) template_dict['impl_arguments'] = ", ".join(data.impl_arguments) template_dict['return_conversion'] = format_escape("".join(data.return_conversion).rstrip()) + template_dict['post_parsing'] = format_escape("".join(data.post_parsing).rstrip()) template_dict['cleanup'] = format_escape("".join(data.cleanup)) template_dict['return_value'] = data.return_value @@ -1367,6 +1375,7 @@ class CLanguage(Language): return_conversion=template_dict['return_conversion'], initializers=template_dict['initializers'], modifications=template_dict['modifications'], + post_parsing=template_dict['post_parsing'], cleanup=template_dict['cleanup'], ) @@ -2595,6 +2604,10 @@ class CConverter(metaclass=CConverterAutoRegister): # parse_arguments self.parse_argument(data.parse_arguments) + # post_parsing + if post_parsing := self.post_parsing(): + data.post_parsing.append('/* Post parse cleanup for ' + name + ' */\n' + post_parsing.rstrip() + '\n') + # cleanup cleanup = self.cleanup() if cleanup: @@ -2686,6 +2699,14 @@ class CConverter(metaclass=CConverterAutoRegister): """ return "" + def post_parsing(self): + """ + The C statements required to do some operations after the end of parsing but before cleaning up. + Return a string containing this code indented at column 0. + If no operation is necessary, return an empty string. + """ + return "" + def cleanup(self): """ The C statements required to clean up after this variable. @@ -3278,10 +3299,10 @@ class str_converter(CConverter): if NoneType in accept and self.c_default == "Py_None": self.c_default = "NULL" - def cleanup(self): + def post_parsing(self): if self.encoding: name = self.name - return "".join(["if (", name, ") {\n PyMem_FREE(", name, ");\n}\n"]) + return f"PyMem_FREE({name});\n" def parse_arg(self, argname, displayname): if self.format_unit == 's': |