8000 Merge branch 'main' into fix-issue-107428 · python/cpython@0966334 · GitHub
[go: up one dir, main page]

Skip to content

Commit 0966334

Browse files
authored
Merge branch 'main' into fix-issue-107428
2 parents 4b06849 + a24e25d commit 0966334

File tree

9 files changed

+74
-19
lines changed

9 files changed

+74
-19
lines changed

.github/CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ Python/traceback.c @iritkatriel
6969

70 8000 70
# Import (including importlib).
7171
**/*import* @brettcannon @ericsnowcurrently @ncoghlan @warsaw
72+
/Python/import.c @kumaraditya303
7273
**/*importlib/resources/* @jaraco @warsaw @FFY00
7374
**/importlib/metadata/* @jaraco @warsaw
7475

Doc/c-api/code.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ bound into a function.
3333
3434
Return the number of free variables in *co*.
3535
36-
.. c:function:: PyCodeObject* PyUnstable_Code_New(int argcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, int firstlineno, PyObject *linetable, PyObject *exceptiontable)
36+
.. c:function:: PyCodeObject* PyUnstable_Code_New(int argcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, PyObject *qualname, int firstlineno, PyObject *linetable, PyObject *exceptiontable)
3737
3838
Return a new code object. If you need a dummy code object to create a frame,
3939
use :c:func:`PyCode_NewEmpty` instead.
@@ -46,7 +46,7 @@ bound into a function.
4646
execution or VM crashes. Use this function only with extreme care.
4747
4848
.. versionchanged:: 3.11
49-
Added ``exceptiontable`` parameter.
49+
Added ``qualname`` and ``exceptiontable`` parameters.
5050
5151
.. index:: single: PyCode_New
5252
@@ -56,7 +56,7 @@ bound into a function.
5656
The old name is deprecated, but will remain available until the
5757
signature changes again.
5858
59-
.. c:function:: PyCodeObject* PyUnstable_Code_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, int firstlineno, PyObject *linetable, PyObject *exceptiontable)
59+
.. c:function:: PyCodeObject* PyUnstable_Code_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, PyObject *qualname, int firstlineno, PyObject *linetable, PyObject *exceptiontable)
6060
6161
Similar to :c:func:`PyUnstable_Code_New`, but with an extra "posonlyargcount" for positional-only arguments.
6262
The same caveats that apply to ``PyUnstable_Code_New`` also apply to this function.
@@ -66,7 +66,7 @@ bound into a function.
6666
.. versionadded:: 3.8 as ``PyCode_NewWithPosOnlyArgs``
6767
6868
.. versionchanged:: 3.11
69-
Added ``exceptiontable`` parameter.
69+
Added ``qualname`` and ``exceptiontable`` parameters.
7070
7171
.. versionchanged:: 3.12
7272

Doc/library/dis.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -922,9 +922,10 @@ iterations of the loop.
922922
.. opcode:: UNPACK_SEQUENCE (count)
923923

924924
Unpacks ``STACK[-1]`` into *count* individual values, which are put onto the stack
925-
right-to-left::
925+
right-to-left. Require there to be exactly *count* values.::
926926

927-
STACK.extend(STACK.pop()[:count:-1])
927+
assert(len(STACK[-1]) == count)
928+
STACK.extend(STACK.pop()[:-count-1:-1])
928929

929930

930931
.. opcode:: UNPACK_EX (counts)

Doc/library/typing.rst

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2329,9 +2329,6 @@ types.
23292329

23302330
class XZ(X, Z): pass # raises TypeError
23312331

2332-
T = TypeVar('T')
2333-
class XT(X, Generic[T]): pass # raises TypeError
2334-
23352332
A ``TypedDict`` can be generic::
23362333

23372334
class Group[T](TypedDict):

Lib/test/test_decimal.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5701,6 +5701,36 @@ def test_c_disallow_instantiation(self):
57015701
ContextManager = type(C.localcontext())
57025702
check_disallow_instantiation(self, ContextManager)
57035703

5704+
def test_c_signaldict_segfault(self):
5705+
# See gh-106263 for details.
5706+
SignalDict = type(C.Context().flags)
5707+
sd = SignalDict()
5708+
err_msg = "invalid signal dict"
5709+
5710+
with self.assertRaisesRegex(ValueError, err_msg):
5711+
len(sd)
5712+
5713+
with self.assertRaisesRegex(ValueError, err_msg):
5714+
iter(sd)
5715+
5716+
with self.assertRaisesRegex(ValueError, err_msg):
5717+
repr(sd)
5718+
5719+
with self.assertRaisesRegex(ValueError, err_msg):
5720+
sd[C.InvalidOperation] = True
5721+
5722+
with self.assertRaisesRegex(ValueError, err_msg):
5723+
sd[C.InvalidOperation]
5724+
5725+
with self.assertRaisesRegex(ValueError, err_msg):
5726+
sd == C.Context().flags
5727+
5728+
with self.assertRaisesRegex(ValueError, err_msg):
5729+
C.Context().flags == sd
5730+
5731+
with self.assertRaisesRegex(ValueError, err_msg):
5732+
sd.copy()
5733+
57045734
@requires_docstrings
57055735
@requires_cdecimal
57065736
class SignatureTest(unittest.TestCase):
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix crash when calling ``repr`` with a manually constructed SignalDict object.
2+
Patch by Charlie Zhao.

Modules/_decimal/_decimal.c

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -314,14 +314,12 @@ value_error_int(const char *mesg)
314314
return -1;
315315
}
316316

317-
#ifdef CONFIG_32
318317
static PyObject *
319318
value_error_ptr(const char *mesg)
320319
{
321320
PyErr_SetString(PyExc_ValueError, mesg);
322321
return NULL;
323322
}
324-
#endif
325323

326324
static int
327325
type_error_int(const char *mesg)
@@ -608,6 +606,8 @@ getround(decimal_state *state, PyObject *v)
608606
initialized to new SignalDicts. Once a SignalDict is tied to
609607
a context, it cannot be deleted. */
610608

609+
static const char *INVALID_SIGNALDICT_ERROR_MSG = "invalid signal dict";
610+
611611
static int
612612
signaldict_init(PyObject *self, PyObject *args UNUSED, PyObject *kwds UNUSED)
613613
{
@@ -616,14 +616,20 @@ signaldict_init(PyObject *self, PyObject *args UNUSED, PyObject *kwds UNUSED)
616616
}
617617

618618
static Py_ssize_t
619-
signaldict_len(PyObject *self UNUSED)
619+
signaldict_len(PyObject *self)
620620
{
621+
if (SdFlagAddr(self) == NULL) {
622+
return value_error_int(INVALID_SIGNALDICT_ERROR_MSG);
623+
}
621624
return SIGNAL_MAP_LEN;
622625
}
623626

624627
static PyObject *
625628
signaldict_iter(PyObject *self)
626629
{
630+
if (SdFlagAddr(self) == NULL) {
631+
return value_error_ptr(INVALID_SIGNALDICT_ERROR_MSG);
632+
}
627633
decimal_state *state = get_module_state_by_def(Py_TYPE(self));
628634
return PyTuple_Type.tp_iter(state->SignalTuple);
629635
}
@@ -632,6 +638,9 @@ static PyObject *
632638
signaldict_getitem(PyObject *self, PyObject *key)
633639
{
634640
uint32_t flag;
641+
if (SdFlagAddr(self) == NULL) {
642+
return value_error_ptr(INVALID_SIGNALDICT_ERROR_MSG);
643+
}
635644
decimal_state *state = get_module_state_by_def(Py_TYPE(self));
636645

637646
flag = exception_as_flag(state, key);
@@ -648,11 +657,15 @@ signaldict_setitem(PyObject *self, PyObject *key, PyObject *value)
648657
uint32_t flag;
649658
int x;
650659

651-
decimal_state *state = get_module_state_by_def(Py_TYPE(self));
660+
if (SdFlagAddr(self) == NULL) {
661+
return value_error_int(INVALID_SIGNALDICT_ERROR_MSG);
662+
}
663+
652664
if (value == NULL) {
653665
return value_error_int("signal keys cannot be deleted");
654666
}
655667

668+
decimal_state *state = get_module_state_by_def(Py_TYPE(self));
656669
flag = exception_as_flag(state, key);
657670
if (flag & DEC_ERRORS) {
658671
return -1;
@@ -697,6 +710,10 @@ signaldict_repr(PyObject *self)
697710
const char *b[SIGNAL_MAP_LEN]; /* bool */
698711
int i;
699712

713+
if (SdFlagAddr(self) == NULL) {
714+
return value_error_ptr(INVALID_SIGNALDICT_ERROR_MSG);
715+
}
716+
700717
assert(SIGNAL_MAP_LEN == 9);
701718

702719
decimal_state *state = get_module_state_by_def(Py_TYPE(self));
@@ -721,6 +738,10 @@ signaldict_richcompare(PyObject *v, PyObject *w, int op)
721738
decimal_state *state = find_state_left_or_right(v, w);
722739
assert(PyDecSignalDict_Check(state, v));
723740

741+
if ((SdFlagAddr(v) == NULL) || (SdFlagAddr(w) == NULL)) {
742+
return value_error_ptr(INVALID_SIGNALDICT_ERROR_MSG);
743+
}
744+
724745
if (op == Py_EQ || op == Py_NE) {
725746
if (PyDecSignalDict_Check(state, w)) {
726747
res = (SdFlags(v)==SdFlags(w)) ^ (op==Py_NE) ? Py_True : Py_False;
@@ -748,6 +769,9 @@ signaldict_richcompare(PyObject *v, PyObject *w, int op)
748769
static PyObject *
749770
signaldict_copy(PyObject *self, PyObject *args UNUSED)
750771
{
772+
if (SdFlagAddr(self) == NULL) {
773+
return value_error_ptr(INVALID_SIGNALDICT_ERROR_MSG);
774+
}
751775
decimal_state *state = get_module_state_by_def(Py_TYPE(self));
752776
return flags_as_dict(state, SdFlags(self));
753777
}

Tools/c-analyzer/cpython/ignored.tsv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ Modules/_decimal/_decimal.c - invalid_rounding_err -
213213
Modules/_decimal/_decimal.c - invalid_signals_err -
214214
Modules/_decimal/_decimal.c - signal_map_template -
215215
Modules/_decimal/_decimal.c - ssize_constants -
216+
Modules/_decimal/_decimal.c - INVALID_SIGNALDICT_ERROR_MSG -
216217
Modules/_elementtree.c - ExpatMemoryHandler -
217218
Modules/_hashopenssl.c - py_hashes -
218219
Modules/_hacl/Hacl_Hash_SHA1.c - _h0 -

Tools/clinic/clinic.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -805,7 +805,8 @@ def docstring_for_c_string(
805805

806806
def output_templates(
807807
self,
808-
f: Function
808+
f: Function,
809+
clinic: Clinic
809810
) -> dict[str, str]:
810811
parameters = list(f.parameters.values())
811812
assert parameters
@@ -1324,7 +1325,6 @@ def parser_body(
13241325
cpp_if = "#if " + conditional
13251326
cpp_endif = "#endif /* " + conditional + " */"
13261327

1327-
assert clinic is not None
13281328
if methoddef_define and f.full_name not in clinic.ifndef_symbols:
13291329
clinic.ifndef_symbols.add(f.full_name)
13301330
methoddef_ifndef = normalize_snippet("""
@@ -1490,7 +1490,7 @@ def render_function(
14901490
parameters = f.render_parameters
14911491
converters = [p.converter for p in parameters]
14921492

1493-
templates = self.output_templates(f)
1493+
templates = self.output_templates(f, clinic)
14941494

14951495
f_self = parameters[0]
14961496
selfless = parameters[1:]
@@ -2015,7 +2015,6 @@ def __post_init__(self, args: tuple[str, ...]) -> None:
20152015
if self.type =='file':
20162016
d = {}
20172017
filename = self.clinic.filename
2018-
assert filename is not None
20192018
d['path'] = filename
20202019
dirname, basename = os.path.split(filename)
20212020
if not dirname:
@@ -2133,8 +2132,8 @@ def __init__(
21332132
language: CLanguage,
21342133
printer: BlockPrinter | None = None,
21352134
*,
2135+
filename: str,
21362136
verify: bool = True,
2137-
filename: str | None = None
21382137
) -> None:
21392138
# maps strings to Parser objects.
21402139
# (instantiated from the "parsers" global.)
@@ -4614,7 +4613,7 @@ def parse(self, block: Block) -> None:
46144613
self.next(self.state_terminal)
46154614
self.state(None)
46164615

4617-
block.output.extend(self.clinic.language.render(clinic, block.signatures))
4616+
block.output.extend(self.clinic.language.render(self.clinic, block.signatures))
46184617

46194618
if self.preserve_output:
46204619
if block.output:

0 commit comments

Comments
 (0)
0