Commit 5592f785 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Support buggy callers of PyString_GET_SIZE

In CPython, PyString_GET_SIZE and PyUnicode_GET_SIZE happen to have
the same implementation, so it is ok for callers to be wrong about
which one they call.

For us, previous to this commit, PyString_GET_SIZE would call PyString_Size,
which has different behavior than PyString_GET_SIZE for non-strings.
For unicode objects it means that we would return the size of the encoded
representation of the string rather than the number of unicode characters.
It also means that PyString_GET_SIZE can fail for us and return -1,
which it never can for CPython, so callers get away with not
checking the return value.
parent 1f434147
......@@ -106,7 +106,14 @@ PyAPI_FUNC(int) _PyString_CheckInterned(PyObject *) PYSTON_NOEXCEPT;
/* Macro, trading safety for speed */
// Pyston changes: these aren't direct macros any more [they potentially could be though]
#define PyString_AS_STRING(op) PyString_AsString((PyObject*)op)
#define PyString_GET_SIZE(op) PyString_Size((PyObject*)op)
// Note: there are buggy extension modules (unicodedata.c) that rely on the fact that
// PyString_GET_SIZE does *not* have the same behavior as PyString_Size. In particular,
// you can get away with calling PyString_GET_SIZE on a unicode object and getting the
// length of the unicode string, not the length of the bytes it encodes to in the default
// encoding.
// So, set up a different function for those callers to use.
PyAPI_FUNC(Py_ssize_t) _PyString_SizeMacro(PyObject *) PYSTON_NOEXCEPT;
#define PyString_GET_SIZE(op) _PyString_SizeMacro((PyObject*)op)
//#define PyString_AS_STRING(op) (((PyStringObject *)(op))->ob_sval)
//#define PyString_GET_SIZE(op) Py_SIZE(op)
......
......@@ -2349,6 +2349,16 @@ extern "C" Py_ssize_t PyString_Size(PyObject* op) noexcept {
return len;
}
extern "C" Py_ssize_t _PyString_SizeMacro(PyObject* op) noexcept {
if (PyString_Check(op))
return static_cast<BoxedString*>(op)->size();
if (PyUnicode_Check(op))
return Py_SIZE(op);
RELEASE_ASSERT(0, "Need to verify the behavior of PyString_GET_SIZE on %s objects", op->cls->tp_name);
}
extern "C" int _PyString_Resize(PyObject** pv, Py_ssize_t newsize) noexcept {
// This is only allowed to be called when there is only one user of the string (ie a refcount of 1 in CPython)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment