Bug 690599 - bug in keystrcmp
Summary: bug in keystrcmp
Status: RESOLVED FIXED
Alias: None
Product: MuPDF
Classification: Unclassified
Component: mupdf (show other bugs)
Version: unspecified
Hardware: PC Windows XP
: P4 normal
Assignee: Tor Andersson
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-07-05 21:10 UTC by Krzysztof Kowalczyk
Modified: 2009-07-21 05:24 UTC (History)
0 users

See Also:
Customer:
Word Size: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Krzysztof Kowalczyk 2009-07-05 21:10:53 UTC
The follwing recently introduced code in keystrcmp():

 if (fz_isstring(key))
   if (strlen(s) == fz_tostrlen(key))
     return memcmp(fz_tostrbuf(key), s, fz_tostrlen(key));

is not correct because it always returns -1 (i.e. s > key) if len(s) !=
len(key). The patch below is one possible fix. I briefly considered using
memcmp(fz_tostrbuf(key), s, min(fz_tostrlen(key), strlen(s)) but that also
doesn't work if one string is a prefix of the other (in which case it would
return 0 instead of 1 or -1). This came up in 
http://code.google.com/p/sumatrapdf/issues/detail?id=557 where outline entries
couldn't be retrieved from outline dictionary due to search in dictionary being
broken thus we couldn't retrieve destination object.

Index: fitz/obj_dict.c
===================================================================
--- fitz/obj_dict.c	(revision 1233)
+++ fitz/obj_dict.c	(working copy)
@@ -15,13 +15,31 @@
 	return -1;
 }
 
+static inline int cmpstr(char *s1, int s1len, char *s2)
+{
+	while ((s1len > 0) && *s2)
+	{
+		unsigned char c1 = *(unsigned char*)s1++;
+		unsigned char c2 = *(unsigned char*)s2++;
+		--s1len;
+		if (c1 > c2)
+			return 1;
+		if (c2 > c1)
+			return -1;
+	}
+	if (s1len > 0)
+		return 1;
+	if (*s2)
+		return -1;
+	return 0;
+}
+
 static inline int keystrcmp(fz_obj *key, char *s)
 {
 	if (fz_isname(key))
 		return strcmp(fz_toname(key), s);
 	if (fz_isstring(key))
-		if (strlen(s) == fz_tostrlen(key))
-			return memcmp(fz_tostrbuf(key), s, fz_tostrlen(key));
+		return cmpstr(fz_tostrbuf(key), fz_tostrlen(key), s);
 	return -1;
 }