Return-Path: Delivered-To: new-httpd-archive@hyperreal.org Received: (qmail 27020 invoked by uid 6000); 17 Nov 1999 14:03:20 -0000 Received: (qmail 27011 invoked from network); 17 Nov 1999 14:03:17 -0000 Received: from slarti.muc.de (193.149.48.10) by taz.hyperreal.org with SMTP; 17 Nov 1999 14:03:17 -0000 Received: (qmail 3817 invoked by uid 66); 17 Nov 1999 14:04:36 -0000 Received: from en by slarti with UUCP; Wed Nov 17 14:04:36 1999 -0000 Received: by en1.engelschall.com (Sendmail 8.9.3+3.2W) for new-httpd@apache.org id NAA51342; Wed, 17 Nov 1999 13:32:39 +0100 (CET) Date: Wed, 17 Nov 1999 13:32:39 +0100 From: "Ralf S. Engelschall" To: Apache Group Developer ML Subject: [PATCH] quad (%qd) formatting in ap_snprintf Message-ID: <19991117133239.A51070@engelschall.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Mailer: Mutt 1.0i Organization: Engelschall, Germany. X-Web-Homepage: http://www.engelschall.com/ X-PGP-Public-Key: https://www.engelschall.com/ho/rse/pgprse.asc X-PGP-Fingerprint: 00 C9 21 8E D1 AB 70 37 DD 67 A2 3A 0A 6F 8D A5 Sender: new-httpd-owner@apache.org Precedence: bulk Reply-To: new-httpd@apache.org Today (on my birthday ;) I've hacked on and cleaned up snprintf implementations for a forthcoming string library and discovered the following bug in ap_snprintf. If one tries to print a "long long" value which is just a little bit lower than the maximimum "unsigned long" (not "unsigned long long"!) value, ap_snprintf treats the value as a (signed) "long" instead of a "long long": | $ cat test.c | #include | #include "ap_config.h" | #include "ap.h" | | int main(int argc, char *argv[]) | { | char buf[1024]; | | ap_snprintf(buf, sizeof(buf), "%qd %qd", 4294967290ULL, 4294967297ULL); | printf("ap_snprintf: \"%s\"\n", buf); | | sprintf(buf, "%qd %qd", 4294967290ULL, 4294967297ULL); | printf("sprintf: \"%s\"\n", buf); | } | $ cc -I../os/unix -I../include -o test test.c libap.a && ./test | ap_snprintf: "-6 4294967297" | sprintf: "4294967290 4294967297" The reason is a wrong optimization test in ap_snprintf.c which can be fixed this way: Index: ap_snprintf.c =================================================================== RCS file: /e/apache/REPOS/apache-1.3/src/ap/ap_snprintf.c,v retrieving revision 1.37 diff -u -r1.37 ap_snprintf.c --- ap_snprintf.c 1999/10/21 20:44:10 1.37 +++ ap_snprintf.c 1999/11/17 12:22:11 @@ -414,7 +413,7 @@ * If the value is less than the maximum unsigned long value, * then we know we aren't using quads, so use the faster function */ - if (num <= ULONG_MAX) + if (num <= ULONG_MAX && is_unsigned) return(conv_10( (wide_int)num, is_unsigned, is_negative, buf_end, len)); With this patch ap_snprintf and the (FreeBSD) vendor sprintf print the same values: | $ cc -I../os/unix -I../include -o test test.c libap.a && ./test | ap_snprintf: "4294967290 4294967297" | sprintf: "4294967290 4294967297" I think the patch is correct, although I have to admit that because of time I've not checked the whole quad-fiddling in ap_snprintf.c now. So I do not commit this myself. Instead someone else should review this first. Greetings, Ralf S. Engelschall rse@engelschall.com www.engelschall.com