tlibsec: avoid undefined C - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 8a2a5b8f2568a665f00741994c1247f0f7d3dffe
 (DIR) parent 01e3847b7e6ff87f72a34a42cd98425e569250f6
 (HTM) Author: Xi Wang <xi.wang@gmail.com>
       Date:   Tue, 19 Mar 2013 14:35:16 -0400
       
       libsec: avoid undefined C
       
       gcc compiles `p + length < p' into 'length < 0' since pointer overflow is undefined behavior in C.  This breaks the check against a large `length'.
       
       Use `length > pend - p' instead.
       
       There's no need to check `length < 0' since `length' is from length_decode() and should be non-negative.
       
       ===
       
       Try the simplified code.
       
       void bar(void);
       void foo(unsigned char *p, int length)
       {
               if (p + length < p)
                       bar();
       }
       
       $ gcc -S -o - t.c -O2
       ...
       foo:
       .LFB0:
               .cfi_startproc
               testl        %esi, %esi
               js        .L4
               rep
               ret
       .L4:
               jmp        bar
               .cfi_endproc
       
       Clearly `p' is not used at all.
       
       R=rsc
       CC=plan9port.codebot
       https://codereview.appspot.com/7231069
       
       Diffstat:
         M src/libsec/port/x509.c              |       3 +--
       
       1 file changed, 1 insertion(+), 2 deletions(-)
       ---
 (DIR) diff --git a/src/libsec/port/x509.c b/src/libsec/port/x509.c
       t@@ -2077,8 +2077,7 @@ digest_certinfo(Bytes *cert, DigestFun digestfun, uchar *digest)
                if(tag_decode(&p, pend, &tag, &isconstr) != ASN_OK ||
                   tag.class != Universal || tag.num != SEQUENCE ||
                   length_decode(&p, pend, &length) != ASN_OK ||
       -           p+length > pend ||
       -           p+length < p)
       +           length > pend - p)
                        return;
                info = p;
                if(ber_decode(&p, pend, &elem) != ASN_OK || elem.tag.num != SEQUENCE)