From c9ffa068d1d1dc93f620994a532f219a4be08385 Mon Sep 17 00:00:00 2001
From: Tim Peters <tim.peters@gmail.com>
Date: Fri, 8 Mar 2002 05:43:32 +0000
Subject: SF bug 515943:  searching for data with \0 in mmap.
 mmap_find_method():  this obtained the string to find via s#, but it ignored
 its length, acting as if it were \0-terminated instead.

Someone please run on Linux too (the extended test_mmap works on Windows).

Bugfix candidate.
---
 Lib/test/test_mmap.py | 25 +++++++++++++++++++++++++
 Modules/mmapmodule.c  | 14 +++++---------
 2 files changed, 30 insertions(+), 9 deletions(-)

diff --git a/Lib/test/test_mmap.py b/Lib/test/test_mmap.py
index f3d1538..0f34758 100644
--- a/Lib/test/test_mmap.py
+++ b/Lib/test/test_mmap.py
@@ -244,6 +244,31 @@ def test_both():
         except OSError:
             pass
 
+    # Do a tougher .find() test.  SF bug 515943 pointed out that, in 2.2,
+    # searching for data with embedded \0 bytes didn't work.
+    f = open(TESTFN, 'w+')
+
+    try:    # unlink TESTFN no matter what
+        data = 'aabaac\x00deef\x00\x00aa\x00'
+        n = len(data)
+        f.write(data)
+        m = mmap.mmap(f.fileno(), n)
+        f.close()
+
+        for start in range(n+1):
+            for finish in range(start, n+1):
+                slice = data[start : finish]
+                vereq(m.find(slice), data.find(slice))
+                vereq(m.find(slice + 'x'), -1)
+
+    finally:
+        try:
+            os.unlink(TESTFN)
+        except OSError:
+            pass
+
+
+
     print ' Test passed'
 
 test_both()
diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c
index cd13914..3164a27 100644
--- a/Modules/mmapmodule.c
+++ b/Modules/mmapmodule.c
@@ -251,20 +251,16 @@ mmap_find_method(mmap_object *self,
 			start = 0;
                 else if ((size_t)start > self->size)
 			start = self->size;
-                p = self->data + start;
 
-		while (p < e) {
-			char *s = p;
-			char *n = needle;
-			while ((s<e) && (*n) && !(*s-*n)) {
-				s++, n++;
-			}
-			if (!*n) {
+		for (p = self->data + start; p + len <= e; ++p) {
+			int i;
+			for (i = 0; i < len && needle[i] == p[i]; ++i)
+				/* nothing */;
+			if (i == len) {
 				return Py_BuildValue (
 					"l",
 					(long) (p - self->data));
 			}
-			p++;
 		}
 		return Py_BuildValue ("l", (long) -1);
 	}
-- 
cgit v0.12

