Rev 3651: Handle references to line data in _patiencediff_c.c properly (Lalinský) in file:///home/pqm/archives/thelove/bzr/%2Btrunk/
Canonical.com Patch Queue Manager
pqm at pqm.ubuntu.com
Wed Aug 27 05:41:43 BST 2008
At file:///home/pqm/archives/thelove/bzr/%2Btrunk/
------------------------------------------------------------
revno: 3651
revision-id: pqm at pqm.ubuntu.com-20080827044137-4ox67ehr4bxtj7b0
parent: pqm at pqm.ubuntu.com-20080826151717-xb3qgwv6xta124k7
parent: aaron at aaronbentley.com-20080827040747-esn1l6aw5zt03sx6
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Wed 2008-08-27 05:41:37 +0100
message:
Handle references to line data in _patiencediff_c.c properly (Lalinský)
modified:
bzrlib/_patiencediff_c.c _patiencediff_c.c-20070721205602-q3imkipwlgagp3cy-1
bzrlib/tests/test_diff.py testdiff.py-20050727164403-d1a3496ebb12e339
------------------------------------------------------------
revno: 3650.1.1
revision-id: aaron at aaronbentley.com-20080827040747-esn1l6aw5zt03sx6
parent: pqm at pqm.ubuntu.com-20080826151717-xb3qgwv6xta124k7
parent: lalinsky at gmail.com-20080823130624-rvbasutb8urxkamy
committer: Aaron Bentley <aaron at aaronbentley.com>
branch nick: bzr.ab.integration
timestamp: Wed 2008-08-27 00:07:47 -0400
message:
Merge patiencediff fix from Lukáš
modified:
bzrlib/_patiencediff_c.c _patiencediff_c.c-20070721205602-q3imkipwlgagp3cy-1
bzrlib/tests/test_diff.py testdiff.py-20050727164403-d1a3496ebb12e339
------------------------------------------------------------
revno: 3628.1.3
revision-id: lalinsky at gmail.com-20080823130624-rvbasutb8urxkamy
parent: lalinsky at gmail.com-20080817193954-xtx7t19otspm7aac
committer: Lukáš Lalinský <lalinsky at gmail.com>
branch nick: patiencediff-refs
timestamp: Sat 2008-08-23 15:06:24 +0200
message:
Add a test
modified:
bzrlib/tests/test_diff.py testdiff.py-20050727164403-d1a3496ebb12e339
------------------------------------------------------------
revno: 3628.1.2
revision-id: lalinsky at gmail.com-20080817193954-xtx7t19otspm7aac
parent: lalinsky at gmail.com-20080817193103-nph9o92j2177iq96
committer: Lukáš Lalinský <lalinsky at gmail.com>
branch nick: patiencediff-refs
timestamp: Sun 2008-08-17 21:39:54 +0200
message:
Actually free the data in delete_lines
modified:
bzrlib/_patiencediff_c.c _patiencediff_c.c-20070721205602-q3imkipwlgagp3cy-1
------------------------------------------------------------
revno: 3628.1.1
revision-id: lalinsky at gmail.com-20080817193103-nph9o92j2177iq96
parent: pqm at pqm.ubuntu.com-20080814042250-v7qws60l3fjwelb1
committer: Lukáš Lalinský <lalinsky at gmail.com>
branch nick: patiencediff-refs
timestamp: Sun 2008-08-17 21:31:03 +0200
message:
Handle references to line data in _patiencediff_c.c properly
This code is called in bzrlib only with lists or tuples of strings, which works fine, because PySequence_Fast always returns the same object and so the items from PySequence_Fast_GET_ITEM will not be deleted until the original sequence is deleted. But if it's called with a sequence than needs to be converted to list (e.g. PyUnicode), the items will be garbage collected in the contructor and still used later in code (which leads to segfaults).
modified:
bzrlib/_patiencediff_c.c _patiencediff_c.c-20070721205602-q3imkipwlgagp3cy-1
=== modified file 'bzrlib/_patiencediff_c.c'
--- a/bzrlib/_patiencediff_c.c 2007-12-19 15:40:04 +0000
+++ b/bzrlib/_patiencediff_c.c 2008-08-17 19:39:54 +0000
@@ -541,6 +541,18 @@
}
+static void
+delete_lines(struct line *lines, Py_ssize_t size)
+{
+ struct line *line = lines;
+ while (size-- > 0) {
+ Py_XDECREF(line->data);
+ line++;
+ }
+ free(lines);
+}
+
+
static Py_ssize_t
load_lines(PyObject *orig, struct line **lines)
{
@@ -559,7 +571,8 @@
return 0;
}
- line = *lines = (struct line *)malloc(sizeof(struct line) * size);
+ /* Allocate a memory block for line data, initialized to 0 */
+ line = *lines = (struct line *)calloc(size, sizeof(struct line));
if (line == NULL) {
PyErr_NoMemory();
Py_DECREF(seq);
@@ -568,6 +581,7 @@
for (i = 0; i < size; i++) {
item = PySequence_Fast_GET_ITEM(seq, i);
+ Py_INCREF(item);
line->data = item;
line->hash = PyObject_Hash(item);
if (line->hash == (-1)) {
@@ -581,6 +595,11 @@
cleanup:
Py_DECREF(seq);
+ if (size == -1) {
+ /* Error -- cleanup unused object references */
+ delete_lines(*lines, i);
+ *lines = NULL;
+ }
return size;
}
@@ -633,16 +652,16 @@
free(backpointers);
free(matches);
free(hashtable.table);
- free(b);
- free(a);
+ delete_lines(b, bsize);
+ delete_lines(a, asize);
return res;
error:
free(backpointers);
free(matches);
free(hashtable.table);
- free(b);
- free(a);
+ delete_lines(b, bsize);
+ delete_lines(a, asize);
return NULL;
}
@@ -711,16 +730,16 @@
free(backpointers);
free(matches.matches);
free(hashtable.table);
- free(b);
- free(a);
+ delete_lines(b, bsize);
+ delete_lines(a, asize);
Py_RETURN_NONE;
error:
free(backpointers);
free(matches.matches);
free(hashtable.table);
- free(b);
- free(a);
+ delete_lines(b, bsize);
+ delete_lines(a, asize);
return NULL;
}
@@ -769,8 +788,8 @@
{
free(self->backpointers);
free(self->hashtable.table);
- free(self->b);
- free(self->a);
+ delete_lines(self->b, self->bsize);
+ delete_lines(self->a, self->asize);
self->ob_type->tp_free((PyObject *)self);
}
=== modified file 'bzrlib/tests/test_diff.py'
--- a/bzrlib/tests/test_diff.py 2008-07-08 14:55:19 +0000
+++ b/bzrlib/tests/test_diff.py 2008-08-23 13:06:24 +0000
@@ -769,6 +769,13 @@
self._PatienceSequenceMatcher = \
bzrlib._patiencediff_py.PatienceSequenceMatcher_py
+ def test_diff_unicode_string(self):
+ a = ''.join([unichr(i) for i in range(4000, 4500, 3)])
+ b = ''.join([unichr(i) for i in range(4300, 4800, 2)])
+ sm = self._PatienceSequenceMatcher(None, a, b)
+ mb = sm.get_matching_blocks()
+ self.assertEquals(35, len(mb))
+
def test_unique_lcs(self):
unique_lcs = self._unique_lcs
self.assertEquals(unique_lcs('', ''), [])
More information about the bazaar-commits
mailing list