avoid a sign-extension bug in crypto_hash_function
authorJim Meyering <meyering@redhat.com>
Sat, 28 May 2011 12:19:08 +0000 (14:19 +0200)
committerJim Meyering <meyering@redhat.com>
Sat, 28 May 2011 12:19:08 +0000 (14:19 +0200)
* fns.c (to_uchar): Define.
(crypto_hash_function): Use it to convert some newly-signed
variables to unsigned, to avoid sign-extension bugs.  For example,
without this change, (md5 "truc") would evaluate to
45723a2aff78ff4fff7fff1114760e62 rather than the expected
45723a2af3788c4ff17f8d1114760e62.  Reported by Antoine Levitt in
http://thread.gmane.org/gmane.emacs.devel/139824

src/ChangeLog
src/fns.c

index 55ee481..cb24722 100644 (file)
@@ -1,3 +1,14 @@
+2011-05-28  Jim Meyering  <meyering@redhat.com>
+
+       avoid a sign-extension bug in crypto_hash_function
+       * fns.c (to_uchar): Define.
+       (crypto_hash_function): Use it to convert some newly-signed
+       variables to unsigned, to avoid sign-extension bugs.  For example,
+       without this change, (md5 "truc") would evaluate to
+       45723a2aff78ff4fff7fff1114760e62 rather than the expected
+       45723a2af3788c4ff17f8d1114760e62.  Reported by Antoine Levitt in
+       http://thread.gmane.org/gmane.emacs.devel/139824
+
 2011-05-27  Paul Eggert  <eggert@cs.ucla.edu>
 
        Integer overflow fixes.
index 3e772d5..f5377d0 100644 (file)
--- a/src/fns.c
+++ b/src/fns.c
@@ -4520,6 +4520,11 @@ including negative integers.  */)
 #include "md5.h"
 #include "sha1.h"
 
+/* Convert a possibly-signed character to an unsigned character.  This is
+   a bit safer than casting to unsigned char, since it catches some type
+   errors that the cast doesn't.  */
+static inline unsigned char to_uchar (char ch) { return ch; }
+
 /* TYPE: 0 for md5, 1 for sha1. */
 
 static Lisp_Object
@@ -4717,7 +4722,7 @@ crypto_hash_function (int type, Lisp_Object object, Lisp_Object start, Lisp_Obje
          {
            char value[33];
            for (i = 0; i < 16; i++)
-             sprintf (&value[2 * i], "%02x", digest[i]);
+             sprintf (&value[2 * i], "%02x", to_uchar (digest[i]));
            res = make_string (value, 32);
          }
        else
@@ -4735,7 +4740,7 @@ crypto_hash_function (int type, Lisp_Object object, Lisp_Object start, Lisp_Obje
          {
            char value[41];
            for (i = 0; i < 20; i++)
-             sprintf (&value[2 * i], "%02x", digest[i]);
+             sprintf (&value[2 * i], "%02x", to_uchar (digest[i]));
            res = make_string (value, 40);
          }
        else