66 ******************************************************************************/
77
88#include "_remote_debugging.h"
9+ #include "internal/pycore_unicodeobject.h" // _Py_MAX_UNICODE
910#include <limits.h>
1011
1112/* ============================================================================
@@ -91,23 +92,15 @@ read_py_str(
9192 }
9293
9394 int kind = (int )state .kind ;
94- Py_UCS4 max_char ;
95- switch (kind ) {
96- case PyUnicode_1BYTE_KIND :
97- max_char = state .ascii ? 0x7F : 0xFF ;
98- break ;
99- case PyUnicode_2BYTE_KIND :
100- max_char = 0xFFFF ;
101- break ;
102- case PyUnicode_4BYTE_KIND :
103- max_char = 0x10FFFF ;
104- break ;
105- default :
106- PyErr_Format (PyExc_RuntimeError ,
107- "Invalid Unicode kind %d at 0x%lx" , kind , address );
108- set_exception_cause (unwinder , PyExc_RuntimeError ,
109- "Invalid kind in remote Unicode object" );
110- return NULL ;
95+ if (kind != PyUnicode_1BYTE_KIND
96+ && kind != PyUnicode_2BYTE_KIND
97+ && kind != PyUnicode_4BYTE_KIND )
98+ {
99+ PyErr_Format (PyExc_RuntimeError ,
100+ "Invalid Unicode kind %d at 0x%lx" , kind , address );
101+ set_exception_cause (unwinder , PyExc_RuntimeError ,
102+ "Invalid kind in remote Unicode object" );
103+ return NULL ;
111104 }
112105
113106 size_t header_size = state .ascii
@@ -127,16 +120,16 @@ read_py_str(
127120 return NULL ;
128121 }
129122
130- PyObject * result = PyUnicode_New (len , max_char );
131- if (result == NULL ) {
132- set_exception_cause (unwinder , PyExc_RuntimeError , "Failed to allocate PyUnicode for remote string" );
133- return NULL ;
134- }
135123 if (nbytes == 0 ) {
136- return result ;
124+ return Py_GetConstant ( Py_CONSTANT_EMPTY_STR ) ;
137125 }
138126
139- void * data = PyUnicode_DATA (result );
127+ char * data = PyMem_Malloc (nbytes );
128+ if (data == NULL ) {
129+ PyErr_NoMemory ();
130+ set_exception_cause (unwinder , PyExc_MemoryError , "Failed to allocate buffer for remote string" );
131+ return NULL ;
132+ }
140133
141134 // Reuse data already present in the header read; only round-trip for
142135 // whatever spills past it.
@@ -153,14 +146,36 @@ read_py_str(
153146 & unwinder -> handle ,
154147 address + header_size + inline_bytes ,
155148 nbytes - inline_bytes ,
156- ( char * ) data + inline_bytes );
149+ data + inline_bytes );
157150 if (res < 0 ) {
158- Py_DECREF ( result );
151+ PyMem_Free ( data );
159152 set_exception_cause (unwinder , PyExc_RuntimeError , "Failed to read string data from remote memory" );
160153 return NULL ;
161154 }
162155 }
163156
157+ if (kind == PyUnicode_4BYTE_KIND ) {
158+ Py_UCS4 * ucs4 = (Py_UCS4 * )data ;
159+ for (Py_ssize_t i = 0 ; i < len ; i ++ ) {
160+ Py_UCS4 ch = ucs4 [i ];
161+ if (ch > _Py_MAX_UNICODE ) {
162+ PyMem_Free (data );
163+ PyErr_Format (PyExc_RuntimeError ,
164+ "character U+%x is not in range [U+0000; U+%x]" ,
165+ ch , _Py_MAX_UNICODE );
166+ set_exception_cause (unwinder , PyExc_RuntimeError ,
167+ "Unicode string contains invalid character" );
168+ return NULL ;
169+ }
170+ }
171+ }
172+
173+ PyObject * result = PyUnicode_FromKindAndData (kind , data , len );
174+ PyMem_Free (data );
175+ if (result == NULL ) {
176+ set_exception_cause (unwinder , PyExc_RuntimeError , "Invalid character data in remote Unicode object" );
177+ return NULL ;
178+ }
164179 return result ;
165180}
166181
0 commit comments