summaryrefslogtreecommitdiff
path: root/Tools/clinic/clinic.py
diff options
context:
space:
mode:
authorSteve Dower <steve.dower@microsoft.com>2017-02-04 15:05:50 -0800
committerSteve Dower <steve.dower@microsoft.com>2017-02-04 15:05:50 -0800
commit3b0e4320092ac0504b6670cafaf0301b908c91fc (patch)
treed3be1b6b844d61763bb366fa21ceed475e5703fd /Tools/clinic/clinic.py
parentb2fa705fd3887c326e811c418469c784353027f4 (diff)
parentf687fbcd73c14dfcbe086eb5cd94b298f1e81e72 (diff)
downloadcpython-3b0e4320092ac0504b6670cafaf0301b908c91fc.tar.gz
Issue #29392: Prevent crash when passing invalid arguments into msvcrt module.
Diffstat (limited to 'Tools/clinic/clinic.py')
-rwxr-xr-xTools/clinic/clinic.py82
1 files changed, 58 insertions, 24 deletions
diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py
index 75ac673737..894d1c5d99 100755
--- a/Tools/clinic/clinic.py
+++ b/Tools/clinic/clinic.py
@@ -705,14 +705,14 @@ class CLanguage(Language):
{c_basename}({self_type}{self_name}, PyObject *args, PyObject *kwargs)
""")
- parser_prototype_fastcall = normalize_snippet("""
+ parser_prototype_varargs = normalize_snippet("""
static PyObject *
- {c_basename}({self_type}{self_name}, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
+ {c_basename}({self_type}{self_name}, PyObject *args)
""")
- parser_prototype_varargs = normalize_snippet("""
+ parser_prototype_fastcall = normalize_snippet("""
static PyObject *
- {c_basename}({self_type}{self_name}, PyObject *args)
+ {c_basename}({self_type}{self_name}, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
""")
# parser_body_fields remembers the fields passed in to the
@@ -825,30 +825,64 @@ class CLanguage(Language):
# and nothing but normal objects:
# PyArg_UnpackTuple!
- flags = "METH_VARARGS"
- parser_prototype = parser_prototype_varargs
+ if not new_or_init:
+ flags = "METH_FASTCALL"
+ parser_prototype = parser_prototype_fastcall
- parser_definition = parser_body(parser_prototype, normalize_snippet("""
- if (!PyArg_UnpackTuple(args, "{name}",
- {unpack_min}, {unpack_max},
- {parse_arguments})) {{
- goto exit;
- }}
- """, indent=4))
+ parser_definition = parser_body(parser_prototype, normalize_snippet("""
+ if (!_PyArg_UnpackStack(args, nargs, "{name}",
+ {unpack_min}, {unpack_max},
+ {parse_arguments})) {{
+ goto exit;
+ }}
+
+ if ({self_type_check}!_PyArg_NoStackKeywords("{name}", kwnames)) {{
+ goto exit;
+ }}
+ """, indent=4))
+ else:
+ flags = "METH_VARARGS"
+ parser_prototype = parser_prototype_varargs
+
+ parser_definition = parser_body(parser_prototype, normalize_snippet("""
+ if (!PyArg_UnpackTuple(args, "{name}",
+ {unpack_min}, {unpack_max},
+ {parse_arguments})) {{
+ goto exit;
+ }}
+ """, indent=4))
elif positional:
- # positional-only, but no option groups
- # we only need one call to PyArg_ParseTuple
+ if not new_or_init:
+ # positional-only, but no option groups
+ # we only need one call to _PyArg_ParseStack
- flags = "METH_VARARGS"
- parser_prototype = parser_prototype_varargs
+ flags = "METH_FASTCALL"
+ parser_prototype = parser_prototype_fastcall
- parser_definition = parser_body(parser_prototype, normalize_snippet("""
- if (!PyArg_ParseTuple(args, "{format_units}:{name}",
- {parse_arguments})) {{
- goto exit;
- }}
- """, indent=4))
+ parser_definition = parser_body(parser_prototype, normalize_snippet("""
+ if (!_PyArg_ParseStack(args, nargs, "{format_units}:{name}",
+ {parse_arguments})) {{
+ goto exit;
+ }}
+
+ if ({self_type_check}!_PyArg_NoStackKeywords("{name}", kwnames)) {{
+ goto exit;
+ }}
+ """, indent=4))
+ else:
+ # positional-only, but no option groups
+ # we only need one call to PyArg_ParseTuple
+
+ flags = "METH_VARARGS"
+ parser_prototype = parser_prototype_varargs
+
+ parser_definition = parser_body(parser_prototype, normalize_snippet("""
+ if (!PyArg_ParseTuple(args, "{format_units}:{name}",
+ {parse_arguments})) {{
+ goto exit;
+ }}
+ """, indent=4))
elif not new_or_init:
flags = "METH_FASTCALL"
@@ -856,7 +890,7 @@ class CLanguage(Language):
parser_prototype = parser_prototype_fastcall
body = normalize_snippet("""
- if (!_PyArg_ParseStack(args, nargs, kwnames, &_parser,
+ if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser,
{parse_arguments})) {{
goto exit;
}}