1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
|
From: Boyuan Yang <byang@debian.org>
Date: Tue, 2 Jul 2024 15:38:46 -0400
Subject: Fix build with Python 3.12
Applied-Upstream: https://sourceforge.net/p/crossfire/crossfire-server/ci/472dd26ac74419baa0e6373cb04e095437e994c6/
---
plugins/cfpython/cjson.c | 51 ++++++++++++------------------------------------
1 file changed, 12 insertions(+), 39 deletions(-)
diff --git a/plugins/cfpython/cjson.c b/plugins/cfpython/cjson.c
index 1483d8f..da1547d 100644
--- a/plugins/cfpython/cjson.c
+++ b/plugins/cfpython/cjson.c
@@ -687,18 +687,14 @@ static PyObject *encode_string(PyObject *string) {
#if defined(IS_PY26) || defined(IS_PY3K)
static PyObject *encode_unicode(PyObject *unicode) {
PyObject *repr;
- Py_UNICODE *s;
- Py_ssize_t size;
+ Py_ssize_t size, pos;
char *p;
static const char *hexdigit = "0123456789abcdef";
-#ifdef Py_UNICODE_WIDE
static const Py_ssize_t expandsize = 10;
-#else
- static const Py_ssize_t expandsize = 6;
-#endif
- s = PyUnicode_AS_UNICODE(unicode);
- size = PyUnicode_GET_SIZE(unicode);
+ int kind = PyUnicode_KIND(unicode);
+ void *data = PyUnicode_DATA(unicode);
+ size = PyUnicode_GET_LENGTH(unicode);
if (size > (PY_SSIZE_T_MAX-2-1)/expandsize) {
PyErr_SetString(PyExc_OverflowError, "unicode object is too large to make repr");
@@ -715,17 +711,21 @@ static PyObject *encode_unicode(PyObject *unicode) {
p = PyByteArray_AS_STRING(repr);
*p++ = '"';
+ pos = 0;
- while (size-- > 0) {
- Py_UNICODE ch = *s++;
+ const Py_UCS4 quote = PyByteArray_AS_STRING(repr)[0];
+
+ while (pos < size) {
+ Py_UCS4 ch = PyUnicode_READ(kind, data, pos);
+ pos++;
/* Escape quotes */
- if ((ch == (Py_UNICODE)PyByteArray_AS_STRING(repr)[0] || ch == '\\')) {
+ if ((ch == quote || ch == '\\')) {
*p++ = '\\';
*p++ = (char)ch;
continue;
}
-#ifdef Py_UNICODE_WIDE
+
/* Map 21-bit characters to '\U00xxxxxx' */
else if (ch >= 0x10000) {
*p++ = '\\';
@@ -740,33 +740,6 @@ static PyObject *encode_unicode(PyObject *unicode) {
*p++ = hexdigit[ch&0x0000000F];
continue;
}
-#else
- /* Map UTF-16 surrogate pairs to Unicode \UXXXXXXXX escapes */
- else if (ch >= 0xD800 && ch < 0xDC00) {
- Py_UNICODE ch2;
- Py_UCS4 ucs;
-
- ch2 = *s++;
- size--;
- if (ch2 >= 0xDC00 && ch2 <= 0xDFFF) {
- ucs = (((ch&0x03FF)<<10)|(ch2&0x03FF))+0x00010000;
- *p++ = '\\';
- *p++ = 'U';
- *p++ = hexdigit[(ucs>>28)&0x0000000F];
- *p++ = hexdigit[(ucs>>24)&0x0000000F];
- *p++ = hexdigit[(ucs>>20)&0x0000000F];
- *p++ = hexdigit[(ucs>>16)&0x0000000F];
- *p++ = hexdigit[(ucs>>12)&0x0000000F];
- *p++ = hexdigit[(ucs>>8)&0x0000000F];
- *p++ = hexdigit[(ucs>>4)&0x0000000F];
- *p++ = hexdigit[ucs&0x0000000F];
- continue;
- }
- /* Fall through: isolated surrogates are copied as-is */
- s--;
- size++;
- }
-#endif
/* Map 16-bit characters to '\uxxxx' */
if (ch >= 256) {
*p++ = '\\';
|