Rev 3845: Write a new function which is safe for all processed strings. in http://bzr.arbash-meinel.com/branches/bzr/brisbane/hack2

John Arbash Meinel john at arbash-meinel.com
Tue Mar 3 04:09:18 GMT 2009


At http://bzr.arbash-meinel.com/branches/bzr/brisbane/hack2

------------------------------------------------------------
revno: 3845
revision-id: john at arbash-meinel.com-20090303040549-lyzw3a730t9me69n
parent: john at arbash-meinel.com-20090303034527-gdvu15fcpz7idixg
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: hack2
timestamp: Mon 2009-03-02 22:05:49 -0600
message:
  Write a new function which is safe for all processed strings.
-------------- next part --------------
=== modified file 'bzrlib/_btree_serializer_c.pyx'
--- a/bzrlib/_btree_serializer_c.pyx	2009-03-03 03:45:27 +0000
+++ b/bzrlib/_btree_serializer_c.pyx	2009-03-03 04:05:49 +0000
@@ -27,21 +27,24 @@
 cdef extern from "Python.h":
     ctypedef int Py_ssize_t # Required for older pyrex versions
     ctypedef struct PyObject:
+        Py_ssize_t ob_refcnt
         pass
     int PyList_Append(object lst, object item) except -1
 
     char *PyString_AsString(object p) except NULL
     object PyString_FromStringAndSize(char *, Py_ssize_t)
+    PyObject *PyString_FromStringAndSize_ptr "PyString_FromStringAndSize" (char *, Py_ssize_t)
     int PyString_CheckExact(object s)
     int PyString_CheckExact_ptr "PyString_CheckExact" (PyObject *)
     Py_ssize_t PyString_Size(object p)
     Py_ssize_t PyString_GET_SIZE_ptr "PyString_GET_SIZE" (PyObject *)
     char * PyString_AS_STRING_ptr "PyString_AS_STRING" (PyObject *)
     int PyString_AsStringAndSize_ptr(PyObject *, char **buf, Py_ssize_t *len)
-    object PyString_InternFromString(char *)
+    void PyString_InternInPlace(PyObject **)
     int PyTuple_CheckExact(object t)
     Py_ssize_t PyTuple_GET_SIZE(object t)
     PyObject *PyTuple_GET_ITEM_ptr_object "PyTuple_GET_ITEM" (object tpl, int index)
+    void Py_DECREF_ptr "Py_DECREF" (PyObject *)
 
 cdef extern from "string.h":
     void *memcpy(void *dest, void *src, size_t n)
@@ -75,6 +78,21 @@
     return PyString_FromStringAndSize(s, size)
 
 
+cdef object safe_interned_string_from_size(char *s, Py_ssize_t size):
+    cdef PyObject *py_str
+    if size < 0:
+        raise AssertionError(
+            'tried to create a string with an invalid size: %d @0x%x'
+            % (size, <int>s))
+    py_str = PyString_FromStringAndSize_ptr(s, size)
+    PyString_InternInPlace(&py_str)
+    result = <object>py_str
+    # Casting a PyObject* to an <object> triggers an INCREF from Pyrex, so we
+    # DECREF it to avoid geting immortal strings
+    Py_DECREF_ptr(py_str)
+    return result
+
+
 cdef class BTreeLeafParser:
     """Parse the leaf nodes of a BTree index.
 
@@ -143,11 +161,8 @@
             # TODO: Consider using PyIntern_FromString, the only caveat is that
             # it assumes a NULL-terminated string, so we have to check if
             # temp_ptr[0] == c'\0' or some other char.
-            if temp_ptr[0] == c'\0':
-                key_element = PyString_InternFromString(self._start)
-            else:
-                key_element = safe_string_from_size(self._start,
-                                                    temp_ptr - self._start)
+            key_element = safe_interned_string_from_size(self._start,
+                                                         temp_ptr - self._start)
             # advance our pointer
             self._start = temp_ptr + 1
             PyList_Append(key_segments, key_element)



More information about the bazaar-commits mailing list