Rev 5029: (mbp) avoid malloc(0) in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Thu Feb 11 06:15:35 GMT 2010


At file:///home/pqm/archives/thelove/bzr/%2Btrunk/

------------------------------------------------------------
revno: 5029 [merge]
revision-id: pqm at pqm.ubuntu.com-20100211061533-5glf4faoutadhql9
parent: pqm at pqm.ubuntu.com-20100211054331-4qtx8q4od2tafla3
parent: mbp at sourcefrog.net-20100211044043-bgwi7alf3sv84zgr
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Thu 2010-02-11 06:15:33 +0000
message:
  (mbp) avoid malloc(0)
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/_patiencediff_c.c       _patiencediff_c.c-20070721205602-q3imkipwlgagp3cy-1
=== modified file 'NEWS'
--- a/NEWS	2010-02-11 05:43:31 +0000
+++ b/NEWS	2010-02-11 06:15:33 +0000
@@ -46,6 +46,9 @@
 * Avoid infinite recursion when probing for apport.
   (Vincent Ladeuil, #516934)
 
+* Avoid ``malloc(0)`` in ``patiencediff``, which is non-portable.
+  (Martin Pool, #331095)
+
 * Network transfer amounts and rates are now displayed in SI units according
   to the Ubuntu Units Policy <https://wiki.ubuntu.com/UnitsPolicy>.
   (Gordon Tyler, #514399)

=== modified file 'bzrlib/_patiencediff_c.c'
--- a/bzrlib/_patiencediff_c.c	2009-10-29 06:11:23 +0000
+++ b/bzrlib/_patiencediff_c.c	2010-02-11 04:39:32 +0000
@@ -1,5 +1,5 @@
 /*
- Copyright (C) 2007 Canonical Ltd
+ Copyright (C) 2007, 2010 Canonical Ltd
 
  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
@@ -46,6 +46,12 @@
 #define SENTINEL -1
 
 
+/* malloc returns NULL on some platforms if you try to allocate nothing,
+ * causing <https://bugs.edge.launchpad.net/bzr/+bug/511267> and
+ * <https://bugs.edge.launchpad.net/bzr/+bug/331095>.  On glibc it passes, but
+ * let's make it fail to aid testing. */
+#define guarded_malloc(x) ( (x) ? malloc(x) : NULL )
+
 enum {
     OP_EQUAL = 0,
     OP_INSERT,
@@ -183,7 +189,8 @@
     while (hsize < bsize + 1)
         hsize *= 2;
 
-    hashtable = (struct bucket *)malloc(sizeof(struct bucket) * hsize);
+    /* can't be 0 */
+    hashtable = (struct bucket *) guarded_malloc(sizeof(struct bucket) * hsize);
     if (hashtable == NULL) {
         PyErr_NoMemory();
         return 0;
@@ -460,7 +467,7 @@
     last_a_pos = alo - 1;
     last_b_pos = blo - 1;
 
-    lcs = (struct matching_line *)malloc(sizeof(struct matching_line) * (bhi - blo));
+    lcs = (struct matching_line *)guarded_malloc(sizeof(struct matching_line) * (bhi - blo));
     if (lcs == NULL)
         return 0;
 
@@ -620,13 +627,15 @@
     if (!equate_lines(&hashtable, a, b, asize, bsize))
         goto error;
 
-    matches = (struct matching_line *)malloc(sizeof(struct matching_line) * bsize);
-    if (matches == NULL)
-        goto error;
+    if (bsize > 0) {
+        matches = (struct matching_line *)guarded_malloc(sizeof(struct matching_line) * bsize);
+        if (matches == NULL)
+            goto error;
 
-    backpointers = (Py_ssize_t *)malloc(sizeof(Py_ssize_t) * bsize * 4);
-    if (backpointers == NULL)
-        goto error;
+        backpointers = (Py_ssize_t *)guarded_malloc(sizeof(Py_ssize_t) * bsize * 4);
+        if (backpointers == NULL)
+            goto error;
+    }
 
     nmatches = unique_lcs(matches, &hashtable, backpointers, a, b, 0, 0, asize, bsize);
 
@@ -692,13 +701,19 @@
         goto error;
 
     matches.count = 0;
-    matches.matches = (struct matching_block *)malloc(sizeof(struct matching_block) * bsize);
-    if (matches.matches == NULL)
-        goto error;
-
-    backpointers = (Py_ssize_t *)malloc(sizeof(Py_ssize_t) * bsize * 4);
-    if (backpointers == NULL)
-        goto error;
+
+    if (bsize > 0) {
+        matches.matches = (struct matching_block *)guarded_malloc(sizeof(struct matching_block) * bsize);
+        if (matches.matches == NULL)
+            goto error;
+
+        backpointers = (Py_ssize_t *)guarded_malloc(sizeof(Py_ssize_t) * bsize * 4);
+        if (backpointers == NULL)
+            goto error;
+    } else {
+        matches.matches = NULL;
+        backpointers = NULL;
+    }
 
     res = recurse_matches(&matches, &hashtable, backpointers,
                           a, b, alo, blo, ahi, bhi, maxrecursion);
@@ -765,11 +780,15 @@
             return NULL;
         }
 
-        self->backpointers = (Py_ssize_t *)malloc(sizeof(Py_ssize_t) * self->bsize * 4);
-        if (self->backpointers == NULL) {
-            Py_DECREF(self);
-            PyErr_NoMemory();
-            return NULL;
+        if (self->bsize > 0) {
+            self->backpointers = (Py_ssize_t *)guarded_malloc(sizeof(Py_ssize_t) * self->bsize * 4);
+            if (self->backpointers == NULL) {
+                Py_DECREF(self);
+                PyErr_NoMemory();
+                return NULL;
+            }
+        } else {
+            self->backpointers = NULL;
         }
 
     }
@@ -812,9 +831,13 @@
     struct matching_blocks matches;
 
     matches.count = 0;
-    matches.matches = (struct matching_block *)malloc(sizeof(struct matching_block) * self->bsize);
-    if (matches.matches == NULL)
-        return PyErr_NoMemory();
+    if (self->bsize > 0) {
+        matches.matches = (struct matching_block *)
+            guarded_malloc(sizeof(struct matching_block) * self->bsize);
+        if (matches.matches == NULL)
+            return PyErr_NoMemory();
+    } else
+        matches.matches = NULL;
 
     res = recurse_matches(&matches, &self->hashtable, self->backpointers,
                           self->a, self->b, 0, 0,
@@ -900,7 +923,7 @@
     struct matching_blocks matches;
 
     matches.count = 0;
-    matches.matches = (struct matching_block *)malloc(sizeof(struct matching_block) * (self->bsize + 1));
+    matches.matches = (struct matching_block *)guarded_malloc(sizeof(struct matching_block) * (self->bsize + 1));
     if (matches.matches == NULL)
         return PyErr_NoMemory();
 
@@ -1013,7 +1036,7 @@
         return NULL;
 
     matches.count = 0;
-    matches.matches = (struct matching_block *)malloc(sizeof(struct matching_block) * (self->bsize + 1));
+    matches.matches = (struct matching_block *)guarded_malloc(sizeof(struct matching_block) * (self->bsize + 1));
     if (matches.matches == NULL)
         return PyErr_NoMemory();
 
@@ -1031,7 +1054,7 @@
     matches.count++;
 
     ncodes = 0;
-    codes = (struct opcode *)malloc(sizeof(struct opcode) * matches.count * 2);
+    codes = (struct opcode *)guarded_malloc(sizeof(struct opcode) * matches.count * 2);
     if (codes == NULL) {
         free(matches.matches);
         return PyErr_NoMemory();
@@ -1252,3 +1275,7 @@
     PyModule_AddObject(m, "PatienceSequenceMatcher_c",
                        (PyObject *)&PatienceSequenceMatcherType);
 }
+
+
+/* vim: sw=4 et 
+ */




More information about the bazaar-commits mailing list