Skip to content

Commit a561275

Browse files
committed
Fix segfaults caused by py_unicode_to_char_star
PyString_AsString returns a pointer to the PyString's buffer. So when we Py_DECREF the string immediately afterwards, this buffer is already free'd. It still works, but is not reliable. Instead, move more of the processing to Perl 6, so we can safely py_dec_ref the string after NativeCall copied it to a Perl 6 string. Fixes htmlify.p6 in perl6/doc.git
1 parent 1ec864e commit a561275

File tree

2 files changed

+15
-16
lines changed

2 files changed

+15
-16
lines changed

lib/Inline/Python.pm6

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,12 @@ sub py_float_as_double(OpaquePointer)
105105
sub py_float_to_py(num64)
106106
returns OpaquePointer { ... }
107107
native(&py_float_to_py);
108-
sub py_unicode_to_char_star(OpaquePointer)
108+
sub py_unicode_as_utf8_string(OpaquePointer)
109+
returns OpaquePointer { ... }
110+
native(&py_unicode_as_utf8_string);
111+
sub py_string_as_string(OpaquePointer)
109112
returns Str { ... }
110-
native(&py_unicode_to_char_star);
113+
native(&py_string_as_string);
111114
sub py_string_to_buf(OpaquePointer, CArray[CArray[int8]])
112115
returns Int { ... }
113116
native(&py_string_to_buf);
@@ -226,7 +229,10 @@ method py_to_p6(OpaquePointer $value) {
226229
return py_float_as_double($value);
227230
}
228231
elsif py_unicode_check($value) {
229-
return py_unicode_to_char_star($value);
232+
my $string = py_unicode_as_utf8_string($value) or return;
233+
my $p6_str = py_string_as_string($string);
234+
py_dec_ref($string);
235+
return $p6_str;
230236
}
231237
elsif py_string_check($value) {
232238
my $string_ptr = CArray[CArray[int8]].new;

pyhelper.c

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -118,24 +118,17 @@ PyObject *py_buf_to_py(int len, char *buf) {
118118
return PyString_FromStringAndSize(buf, len);
119119
}
120120

121-
char *py_unicode_to_char_star(PyObject *obj) {
122-
PyObject * const string = PyUnicode_AsUTF8String(obj); /* new reference */
123-
if (!string) {
124-
return NULL;
125-
}
126-
char * const str = PyString_AsString(string);
127-
Py_DECREF(string);
128-
return str;
121+
PyObject *py_unicode_as_utf8_string(PyObject *obj) {
122+
return PyUnicode_AsUTF8String(obj); /* new reference */
123+
}
124+
125+
char *py_string_as_string(PyObject *obj) {
126+
return PyString_AsString(obj);
129127
}
130128

131129
Py_ssize_t py_string_to_buf(PyObject *obj, char **buf) {
132-
PyObject * const string = PyObject_Str(obj); /* new reference */
133-
if (!string) {
134-
return 0;
135-
}
136130
Py_ssize_t length;
137131
PyString_AsStringAndSize(obj, buf, &length);
138-
Py_DECREF(string);
139132
return length;
140133
}
141134

0 commit comments

Comments
 (0)