Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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
  • Loading branch information
niner committed Feb 23, 2015
1 parent 1ec864e commit a561275
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 16 deletions.
12 changes: 9 additions & 3 deletions lib/Inline/Python.pm6
Expand Up @@ -105,9 +105,12 @@ sub py_float_as_double(OpaquePointer)
sub py_float_to_py(num64)
returns OpaquePointer { ... }
native(&py_float_to_py);
sub py_unicode_to_char_star(OpaquePointer)
sub py_unicode_as_utf8_string(OpaquePointer)
returns OpaquePointer { ... }
native(&py_unicode_as_utf8_string);
sub py_string_as_string(OpaquePointer)
returns Str { ... }
native(&py_unicode_to_char_star);
native(&py_string_as_string);
sub py_string_to_buf(OpaquePointer, CArray[CArray[int8]])
returns Int { ... }
native(&py_string_to_buf);
Expand Down Expand Up @@ -226,7 +229,10 @@ method py_to_p6(OpaquePointer $value) {
return py_float_as_double($value);
}
elsif py_unicode_check($value) {
return py_unicode_to_char_star($value);
my $string = py_unicode_as_utf8_string($value) or return;
my $p6_str = py_string_as_string($string);
py_dec_ref($string);
return $p6_str;
}
elsif py_string_check($value) {
my $string_ptr = CArray[CArray[int8]].new;
Expand Down
19 changes: 6 additions & 13 deletions pyhelper.c
Expand Up @@ -118,24 +118,17 @@ PyObject *py_buf_to_py(int len, char *buf) {
return PyString_FromStringAndSize(buf, len);
}

char *py_unicode_to_char_star(PyObject *obj) {
PyObject * const string = PyUnicode_AsUTF8String(obj); /* new reference */
if (!string) {
return NULL;
}
char * const str = PyString_AsString(string);
Py_DECREF(string);
return str;
PyObject *py_unicode_as_utf8_string(PyObject *obj) {
return PyUnicode_AsUTF8String(obj); /* new reference */
}

char *py_string_as_string(PyObject *obj) {
return PyString_AsString(obj);
}

Py_ssize_t py_string_to_buf(PyObject *obj, char **buf) {
PyObject * const string = PyObject_Str(obj); /* new reference */
if (!string) {
return 0;
}
Py_ssize_t length;
PyString_AsStringAndSize(obj, buf, &length);
Py_DECREF(string);
return length;
}

Expand Down

0 comments on commit a561275

Please sign in to comment.