Skip to content

Commit 9307e7d

Browse files
bpo-41991: Remove _PyObject_HasAttrId
It can silence arbitrary exceptions.
1 parent a427593 commit 9307e7d

File tree

5 files changed

+28
-22
lines changed

5 files changed

+28
-22
lines changed

Include/cpython/object.h

-1
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,6 @@ PyAPI_FUNC(int) _PyObject_IsFreed(PyObject *);
306306
PyAPI_FUNC(int) _PyObject_IsAbstract(PyObject *);
307307
PyAPI_FUNC(PyObject *) _PyObject_GetAttrId(PyObject *, struct _Py_Identifier *);
308308
PyAPI_FUNC(int) _PyObject_SetAttrId(PyObject *, struct _Py_Identifier *, PyObject *);
309-
PyAPI_FUNC(int) _PyObject_HasAttrId(PyObject *, struct _Py_Identifier *);
310309
/* Replacements of PyObject_GetAttr() and _PyObject_GetAttrId() which
311310
don't raise AttributeError.
312311

Objects/object.c

-11
Original file line numberDiff line numberDiff line change
@@ -854,17 +854,6 @@ _PyObject_GetAttrId(PyObject *v, _Py_Identifier *name)
854854
return result;
855855
}
856856

857-
int
858-
_PyObject_HasAttrId(PyObject *v, _Py_Identifier *name)
859-
{
860-
int result;
861-
PyObject *oname = _PyUnicode_FromId(name); /* borrowed */
862-
if (!oname)
863-
return -1;
864-
result = PyObject_HasAttr(v, oname);
865-
return result;
866-
}
867-
868857
int
869858
_PyObject_SetAttrId(PyObject *v, _Py_Identifier *name, PyObject *w)
870859
{

Objects/unionobject.c

+7-6
Original file line numberDiff line numberDiff line change
@@ -311,21 +311,22 @@ union_repr_item(_PyUnicodeWriter *writer, PyObject *p)
311311
_Py_IDENTIFIER(__args__);
312312
PyObject *qualname = NULL;
313313
PyObject *module = NULL;
314+
PyObject *tmp;
314315
PyObject *r = NULL;
315316
int err;
316317

317-
int has_origin = _PyObject_HasAttrId(p, &PyId___origin__);
318-
if (has_origin < 0) {
318+
if (_PyObject_LookupAttrId(p, &PyId___origin__, &tmp) < 0) {
319319
goto exit;
320320
}
321321

322-
if (has_origin) {
323-
int has_args = _PyObject_HasAttrId(p, &PyId___args__);
324-
if (has_args < 0) {
322+
if (tmp) {
323+
Py_DECREF(tmp);
324+
if (_PyObject_LookupAttrId(p, &PyId___args__, &tmp) < 0) {
325325
goto exit;
326326
}
327-
if (has_args) {
327+
if (tmp) {
328328
// It looks like a GenericAlias
329+
Py_DECREF(tmp);
329330
goto use_repr;
330331
}
331332
}

Python/errors.c

+17-2
Original file line numberDiff line numberDiff line change
@@ -1593,9 +1593,18 @@ PyErr_SyntaxLocationObject(PyObject *filename, int lineno, int col_offset)
15931593
}
15941594
Py_DECREF(tmp);
15951595
}
1596+
else {
1597+
_PyErr_Clear(tstate);
1598+
}
15961599
}
15971600
if (exc != PyExc_SyntaxError) {
1598-
if (!_PyObject_HasAttrId(v, &PyId_msg)) {
1601+
if (_PyObject_LookupAttrId(v, &PyId_msg, &tmp) < 0) {
1602+
_PyErr_Clear(tstate);
1603+
}
1604+
else if (tmp) {
1605+
Py_DECREF(tmp);
1606+
}
1607+
else {
15991608
tmp = PyObject_Str(v);
16001609
if (tmp) {
16011610
if (_PyObject_SetAttrId(v, &PyId_msg, tmp)) {
@@ -1607,7 +1616,13 @@ PyErr_SyntaxLocationObject(PyObject *filename, int lineno, int col_offset)
16071616
_PyErr_Clear(tstate);
16081617
}
16091618
}
1610-
if (!_PyObject_HasAttrId(v, &PyId_print_file_and_line)) {
1619+
if (_PyObject_LookupAttrId(v, &PyId_print_file_and_line, &tmp) < 0) {
1620+
_PyErr_Clear(tstate);
1621+
}
1622+
else if (tmp) {
1623+
Py_DECREF(tmp);
1624+
}
1625+
else {
16111626
if (_PyObject_SetAttrId(v, &PyId_print_file_and_line,
16121627
Py_None)) {
16131628
_PyErr_Clear(tstate);

Python/pythonrun.c

+4-2
Original file line numberDiff line numberDiff line change
@@ -770,7 +770,7 @@ static void
770770
print_exception(PyObject *f, PyObject *value)
771771
{
772772
int err = 0;
773-
PyObject *type, *tb;
773+
PyObject *type, *tb, *tmp;
774774
_Py_IDENTIFIER(print_file_and_line);
775775

776776
if (!PyExceptionInstance_Check(value)) {
@@ -789,10 +789,12 @@ print_exception(PyObject *f, PyObject *value)
789789
if (tb && tb != Py_None)
790790
err = PyTraceBack_Print(tb, f);
791791
if (err == 0 &&
792-
_PyObject_HasAttrId(value, &PyId_print_file_and_line))
792+
(err = _PyObject_LookupAttrId(value, &PyId_print_file_and_line, &tmp)) > 0)
793793
{
794794
PyObject *message, *filename, *text;
795795
Py_ssize_t lineno, offset;
796+
err = 0;
797+
Py_DECREF(tmp);
796798
if (!parse_syntax_error(value, &message, &filename,
797799
&lineno, &offset, &text))
798800
PyErr_Clear();

0 commit comments

Comments
 (0)