Skip to content

Commit 0bee8b9

Browse files
committed
protect against objects that have no str() representation
1 parent 3b0682d commit 0bee8b9

File tree

3 files changed

+53
-28
lines changed

3 files changed

+53
-28
lines changed

direct/src/dcparser/dcField.cxx

Lines changed: 48 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -261,9 +261,7 @@ pack_args(DCPacker &packer, PyObject *sequence) const {
261261
packer.pack_object(sequence);
262262
if (!packer.had_error()) {
263263
/*
264-
PyObject *str = PyObject_Str(sequence);
265-
cerr << "pack " << get_name() << PyString_AsString(str) << "\n";
266-
Py_DECREF(str);
264+
cerr << "pack " << get_name() << get_pystr(sequence) << "\n";
267265
*/
268266

269267
return true;
@@ -276,47 +274,36 @@ pack_args(DCPacker &packer, PyObject *sequence) const {
276274
if (as_parameter() != (DCParameter *)NULL) {
277275
// If it's a parameter-type field, the value may or may not be a
278276
// sequence.
279-
PyObject *str = PyObject_Str(sequence);
280-
nassertr(str != (PyObject *)NULL, false);
281-
282277
if (packer.had_pack_error()) {
283278
strm << "Incorrect arguments to field: " << get_name()
284-
<< " = " << PyString_AsString(str);
279+
<< " = " << get_pystr(sequence);
285280
exc_type = PyExc_TypeError;
286281
} else {
287282
strm << "Value out of range on field: " << get_name()
288-
<< " = " << PyString_AsString(str);
283+
<< " = " << get_pystr(sequence);
289284
exc_type = PyExc_ValueError;
290285
}
291-
Py_DECREF(str);
292286

293287
} else {
294288
// If it's a molecular or atomic field, the value should be a
295289
// sequence.
296290
PyObject *tuple = PySequence_Tuple(sequence);
297291
if (tuple == (PyObject *)NULL) {
298-
PyObject *str = PyObject_Str(sequence);
299-
nassertr(str != (PyObject *)NULL, false);
300-
301292
strm << "Value for " << get_name() << " not a sequence: " \
302-
<< PyString_AsString(str);
293+
<< get_pystr(sequence);
303294
exc_type = PyExc_TypeError;
304-
Py_DECREF(str);
305295

306296
} else {
307-
PyObject *str = PyObject_Str(tuple);
308-
309297
if (packer.had_pack_error()) {
310298
strm << "Incorrect arguments to field: " << get_name()
311-
<< PyString_AsString(str);
299+
<< get_pystr(sequence);
312300
exc_type = PyExc_TypeError;
313301
} else {
314302
strm << "Value out of range on field: " << get_name()
315-
<< PyString_AsString(str);
303+
<< get_pystr(sequence);
316304
exc_type = PyExc_ValueError;
317305
}
318306

319-
Py_DECREF(str);
320307
Py_DECREF(tuple);
321308
}
322309
}
@@ -350,9 +337,7 @@ unpack_args(DCPacker &packer) const {
350337
if (!packer.had_error()) {
351338
// Successfully unpacked.
352339
/*
353-
PyObject *str = PyObject_Str(object);
354-
cerr << "recv " << get_name() << PyString_AsString(str) << "\n";
355-
Py_DECREF(str);
340+
cerr << "recv " << get_name() << get_pystr(object) << "\n";
356341
*/
357342

358343
return object;
@@ -375,10 +360,8 @@ unpack_args(DCPacker &packer) const {
375360

376361
exc_type = PyExc_RuntimeError;
377362
} else {
378-
PyObject *str = PyObject_Str(object);
379363
strm << "Value outside specified range when unpacking field "
380-
<< get_name() << ": " << PyString_AsString(str);
381-
Py_DECREF(str);
364+
<< get_name() << ": " << get_pystr(object);
382365
exc_type = PyExc_ValueError;
383366
}
384367

@@ -587,6 +570,46 @@ set_name(const string &name) {
587570
}
588571
}
589572

573+
#ifdef HAVE_PYTHON
574+
////////////////////////////////////////////////////////////////////
575+
// Function: DCField::get_pystr
576+
// Access: Public, Static
577+
// Description: Returns the string representation of the indicated
578+
// Python object.
579+
////////////////////////////////////////////////////////////////////
580+
string DCField::
581+
get_pystr(PyObject *value) {
582+
if (value == NULL) {
583+
return "(null)";
584+
}
585+
586+
PyObject *str = PyObject_Str(value);
587+
if (str != NULL) {
588+
string result = PyString_AsString(str);
589+
Py_DECREF(str);
590+
return result;
591+
}
592+
593+
PyObject *repr = PyObject_Repr(value);
594+
if (repr != NULL) {
595+
string result = PyString_AsString(repr);
596+
Py_DECREF(repr);
597+
return result;
598+
}
599+
600+
if (value->ob_type != NULL) {
601+
PyObject *typestr = PyObject_Str((PyObject *)(value->ob_type));
602+
if (typestr != NULL) {
603+
string result = PyString_AsString(typestr);
604+
Py_DECREF(typestr);
605+
return result;
606+
}
607+
}
608+
609+
return "(invalid object)";
610+
}
611+
#endif // HAVE_PYTHON
612+
590613
////////////////////////////////////////////////////////////////////
591614
// Function: DCField::refresh_default_value
592615
// Access: Protected

direct/src/dcparser/dcField.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ class EXPCL_DIRECT DCField : public DCPackerInterface, public DCKeywordList {
103103
INLINE void set_class(DCClass *dclass);
104104
INLINE void set_default_value(const string &default_value);
105105

106+
#ifdef HAVE_PYTHON
107+
static string get_pystr(PyObject *value);
108+
#endif
109+
106110
protected:
107111
void refresh_default_value();
108112

direct/src/dcparser/dcPacker.cxx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -829,10 +829,8 @@ pack_object(PyObject *object) {
829829
// expecting a class parameter. This is none of the above, an
830830
// error.
831831
ostringstream strm;
832-
PyObject *str = PyObject_Str(object);
833832
strm << "Don't know how to pack object: "
834-
<< PyString_AsString(str) << "\n";
835-
Py_DECREF(str);
833+
<< DCField::get_pystr(object);
836834
nassert_raise(strm.str());
837835
_pack_error = true;
838836
}

0 commit comments

Comments
 (0)