{"thread":{"id":"20491","subject":"[PATCH] fix potential infinite loop given large unsigned integer","startedAt":"2009-08-09T04:41:21Z","lastAt":"2009-08-11T00:55:17Z","messageCount":14,"participants":["Ryan Flynn","Junio C Hamano","Erik Faye-Lund","Christian Couder","Johannes Schindelin","Tony Finch","Jeff Epler"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"120027","messageId":"a3f15ee60908082141l7b2134cg5ddcef17c45fc888@mail.gmail.com","threadId":"20491","inReplyTo":null,"subject":"[PATCH] fix potential infinite loop given large unsigned integer","fromName":"Ryan Flynn","fromEmail":"parseerror@gmail.com","sentAt":"2009-08-09T04:41:21Z","receivedAt":"2009-08-09T04:41:21Z","isPatch":true,"sender":{"key":"parseerror@gmail.com","avatar":"https://gravatar.com/avatar/2dc363300e09c898bd11688dcbe703e82e0102e810b93bd96d6287d32d26c4c0?d=mp&s=160"},"body":"given n, tried to find i greater than n via i=1, iterate i *= 10.\ngiven n sufficiently close to UINT_MAX this will overflow; which can\nproduce i==0, which results in an infinite loop. iteratively dividing\nn /= 10 does not have this problem, and though division is slower than\nmultiplication this only runs once per `git format-patch\n--cover-letter`\n\nSigned-off-by: pizza <parseerror@gmail.com>\n---\n log-tree.c |    6 +++---\n 1 files changed, 3 insertions(+), 3 deletions(-)\n\ndiff --git a/log-tree.c b/log-tree.c\nindex 6f73c17..53a1bd2 100644\n--- a/log-tree.c\n+++ b/log-tree.c\n@@ -160,9 +160,9 @@ static void append_signoff(struct strbuf *sb,\nconst char *signoff)\n\n static unsigned int digits_in_number(unsigned int number)\n {\n-       unsigned int i = 10, result = 1;\n-       while (i <= number) {\n-               i *= 10;\n+       unsigned int result = 1;\n+       while (number > 9) {\n+    number /= 10;\n                result++;\n        }\n        return result;\n-- \n1.6.0.4\n"},{"id":"120028","messageId":"7vy6pta4rd.fsf@alter.siamese.dyndns.org","threadId":"20491","inReplyTo":"a3f15ee60908082141l7b2134cg5ddcef17c45fc888@mail.gmail.com","subject":"Re: [PATCH] fix potential infinite loop given large unsigned integer","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-08-09T06:19:18Z","receivedAt":"2009-08-09T06:19:18Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ryan Flynn <parseerror@gmail.com> writes:\n\n> given n, tried to find i greater than n via i=1, iterate i *= 10.\n> given n sufficiently close to UINT_MAX this will overflow; which can\n> produce i==0, which results in an infinite loop. iteratively dividing\n> n /= 10 does not have this problem, and though division is slower than\n> multiplication this only runs once per `git format-patch\n> --cover-letter`\n>\n> Signed-off-by: pizza <parseerror@gmail.com>\n\nPizza?\n\nThis is somewhat amusing.\n\n - digits_in_number() is called only with opt->total that is \"int\";\n\n - opt->total is the total number of patches.\n\n - the return value is used like this:\n\n     sprintf(buf, \"%0*d\", digits_in_number(opt->total), opt->nr);\n\n   and opt->nr runs from 1 to opt->total; the use of \"d\" would be already\n   wrong anyway even if you computed digits_in_number() correctly.\n\nPerhaps we should get rid of this function altogether?\n"},{"id":"120034","messageId":"7v3a81a13z.fsf@alter.siamese.dyndns.org","threadId":"20491","inReplyTo":"7vy6pta4rd.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] fix potential infinite loop given large unsigned integer","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-08-09T07:38:08Z","receivedAt":"2009-08-09T07:38:08Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Ryan Flynn <parseerror@gmail.com> writes:\n>\n>> given n, tried to find i greater than n via i=1, iterate i *= 10.\n>> given n sufficiently close to UINT_MAX this will overflow; which can\n>> produce i==0, which results in an infinite loop. iteratively dividing\n>> n /= 10 does not have this problem, and though division is slower than\n>> multiplication this only runs once per `git format-patch\n>> --cover-letter`\n>>\n>> Signed-off-by: pizza <parseerror@gmail.com>\n>\n> Pizza?\n>\n> This is somewhat amusing.\n>\n>  - digits_in_number() is called only with opt->total that is \"int\";\n>\n>  - opt->total is the total number of patches.\n>\n>  - the return value is used like this:\n>\n>      sprintf(buf, \"%0*d\", digits_in_number(opt->total), opt->nr);\n>\n>    and opt->nr runs from 1 to opt->total; the use of \"d\" would be already\n>    wrong anyway even if you computed digits_in_number() correctly.\n>\n> Perhaps we should get rid of this function altogether?\n\nOr perhaps something stupid like this...\n\n builtin-log.c |    6 +++++-\n log-tree.c    |   12 +-----------\n revision.h    |    2 +-\n 3 files changed, 7 insertions(+), 13 deletions(-)\n\ndiff --git a/builtin-log.c b/builtin-log.c\nindex 3817bf1..321e8f5 100644\n--- a/builtin-log.c\n+++ b/builtin-log.c\n@@ -1096,8 +1096,12 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n \ttotal = nr;\n \tif (!keep_subject && auto_number && total > 1)\n \t\tnumbered = 1;\n-\tif (numbered)\n+\tif (numbered) {\n+\t\tstatic char num_buf[64];\n \t\trev.total = total + start_number - 1;\n+\t\tsprintf(num_buf, \"%d\", rev.total);\n+\t\trev.num_width = strlen(num_buf);\n+\t}\n \tif (in_reply_to || thread || cover_letter)\n \t\trev.ref_message_ids = xcalloc(1, sizeof(struct string_list));\n \tif (in_reply_to) {\ndiff --git a/log-tree.c b/log-tree.c\nindex 6f73c17..0d32a6c 100644\n--- a/log-tree.c\n+++ b/log-tree.c\n@@ -158,16 +158,6 @@ static void append_signoff(struct strbuf *sb, const char *signoff)\n \tstrbuf_addch(sb, '\\n');\n }\n \n-static unsigned int digits_in_number(unsigned int number)\n-{\n-\tunsigned int i = 10, result = 1;\n-\twhile (i <= number) {\n-\t\ti *= 10;\n-\t\tresult++;\n-\t}\n-\treturn result;\n-}\n-\n static int has_non_ascii(const char *s)\n {\n \tint ch;\n@@ -212,7 +202,7 @@ void log_write_email_headers(struct rev_info *opt, struct commit *commit,\n \t\tsnprintf(buffer, sizeof(buffer),\n \t\t\t \"Subject: [%s %0*d/%d] \",\n \t\t\t opt->subject_prefix,\n-\t\t\t digits_in_number(opt->total),\n+\t\t\t opt->num_width,\n \t\t\t opt->nr, opt->total);\n \t\tsubject = buffer;\n \t} else if (opt->total == 0 && opt->subject_prefix && *opt->subject_prefix) {\ndiff --git a/revision.h b/revision.h\nindex fb74492..21e4d9d 100644\n--- a/revision.h\n+++ b/revision.h\n@@ -84,7 +84,7 @@ struct rev_info {\n \tunsigned int\tabbrev;\n \tenum cmit_fmt\tcommit_format;\n \tstruct log_info *loginfo;\n-\tint\t\tnr, total;\n+\tint\t\tnr, total, num_width;\n \tconst char\t*mime_boundary;\n \tconst char\t*patch_suffix;\n \tint\t\tnumbered_files;\n"},{"id":"120050","messageId":"40aa078e0908090525h7b4d6efeh658e2edcfbe16c7e@mail.gmail.com","threadId":"20491","inReplyTo":"7v3a81a13z.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] fix potential infinite loop given large unsigned integer","fromName":"Erik Faye-Lund","fromEmail":"kusmabite@googlemail.com","sentAt":"2009-08-09T12:25:40Z","receivedAt":"2009-08-09T12:25:40Z","isPatch":true,"sender":{"key":"kusmabite@gmail.com","avatar":"https://avatars.githubusercontent.com/u/47073?v=4"},"body":"On Sun, Aug 9, 2009 at 9:38 AM, Junio C Hamano<gitster@pobox.com> wrote:\n> +               static char num_buf[64];\n>                rev.total = total + start_number - 1;\n> +               sprintf(num_buf, \"%d\", rev.total);\n> +               rev.num_width = strlen(num_buf);\n\nhow about\nrev.num_width = (int)log10((double)rev.total) + 1;\n\nhm?\n\nlog10() appears to be C99, but can be emulated on earlier C-versions by doing\n#define log10(x) (log(x) / log(10.0))\n\n-- \nErik \"kusma\" Faye-Lund\nkusmabite@gmail.com\n(+47) 986 59 656\n"},{"id":"120098","messageId":"a3f15ee60908091616v3ce41374x873a0cf473d0bd3@mail.gmail.com","threadId":"20491","inReplyTo":"7vy6pta4rd.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] fix potential infinite loop given large unsigned integer","fromName":"Ryan Flynn","fromEmail":"parseerror@gmail.com","sentAt":"2009-08-09T23:16:38Z","receivedAt":"2009-08-09T23:16:38Z","isPatch":true,"sender":{"key":"parseerror@gmail.com","avatar":"https://gravatar.com/avatar/2dc363300e09c898bd11688dcbe703e82e0102e810b93bd96d6287d32d26c4c0?d=mp&s=160"},"body":"> Perhaps we should get rid of this function altogether?\n\nI was thinking of something like that, but figured i'd start small and\nfix the bug first.\n"},{"id":"120099","messageId":"a3f15ee60908091723l3e8a29adw8fbc990f4b0925db@mail.gmail.com","threadId":"20491","inReplyTo":"7v3a81a13z.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] fix potential infinite loop given large unsigned integer","fromName":"Ryan Flynn","fromEmail":"parseerror@gmail.com","sentAt":"2009-08-10T00:23:18Z","receivedAt":"2009-08-10T00:23:18Z","isPatch":true,"sender":{"key":"parseerror@gmail.com","avatar":"https://gravatar.com/avatar/2dc363300e09c898bd11688dcbe703e82e0102e810b93bd96d6287d32d26c4c0?d=mp&s=160"},"body":"On Sun, Aug 9, 2009 at 3:38 AM, Junio C Hamano<gitster@pobox.com> wrote:\n> Junio C Hamano <gitster@pobox.com> writes:\n>\n>> Ryan Flynn <parseerror@gmail.com> writes:\n>>\n>>> given n, tried to find i greater than n via i=1, iterate i *= 10.\n>>> given n sufficiently close to UINT_MAX this will overflow; which can\n>>> produce i==0, which results in an infinite loop. iteratively dividing\n>>> n /= 10 does not have this problem, and though division is slower than\n>>> multiplication this only runs once per `git format-patch\n>>> --cover-letter`\n>>>\n>>> Signed-off-by: pizza <parseerror@gmail.com>\n>>\n>> Pizza?\n>>\n>> This is somewhat amusing.\n>>\n>>  - digits_in_number() is called only with opt->total that is \"int\";\n>>\n>>  - opt->total is the total number of patches.\n>>\n>>  - the return value is used like this:\n>>\n>>      sprintf(buf, \"%0*d\", digits_in_number(opt->total), opt->nr);\n>>\n>>    and opt->nr runs from 1 to opt->total; the use of \"d\" would be already\n>>    wrong anyway even if you computed digits_in_number() correctly.\n>>\n>> Perhaps we should get rid of this function altogether?\n>\n> Or perhaps something stupid like this...\n>\n>  builtin-log.c |    6 +++++-\n>  log-tree.c    |   12 +-----------\n>  revision.h    |    2 +-\n>  3 files changed, 7 insertions(+), 13 deletions(-)\n>\n> diff --git a/builtin-log.c b/builtin-log.c\n> index 3817bf1..321e8f5 100644\n> --- a/builtin-log.c\n> +++ b/builtin-log.c\n> @@ -1096,8 +1096,12 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n>        total = nr;\n>        if (!keep_subject && auto_number && total > 1)\n>                numbered = 1;\n> -       if (numbered)\n> +       if (numbered) {\n> +               static char num_buf[64];\n>                rev.total = total + start_number - 1;\n> +               sprintf(num_buf, \"%d\", rev.total);\n> +               rev.num_width = strlen(num_buf);\n> +       }\n>        if (in_reply_to || thread || cover_letter)\n>                rev.ref_message_ids = xcalloc(1, sizeof(struct string_list));\n>        if (in_reply_to) {\n> diff --git a/log-tree.c b/log-tree.c\n> index 6f73c17..0d32a6c 100644\n> --- a/log-tree.c\n> +++ b/log-tree.c\n> @@ -158,16 +158,6 @@ static void append_signoff(struct strbuf *sb, const char *signoff)\n>        strbuf_addch(sb, '\\n');\n>  }\n>\n> -static unsigned int digits_in_number(unsigned int number)\n> -{\n> -       unsigned int i = 10, result = 1;\n> -       while (i <= number) {\n> -               i *= 10;\n> -               result++;\n> -       }\n> -       return result;\n> -}\n> -\n>  static int has_non_ascii(const char *s)\n>  {\n>        int ch;\n> @@ -212,7 +202,7 @@ void log_write_email_headers(struct rev_info *opt, struct commit *commit,\n>                snprintf(buffer, sizeof(buffer),\n>                         \"Subject: [%s %0*d/%d] \",\n>                         opt->subject_prefix,\n> -                        digits_in_number(opt->total),\n> +                        opt->num_width,\n>                         opt->nr, opt->total);\n>                subject = buffer;\n>        } else if (opt->total == 0 && opt->subject_prefix && *opt->subject_prefix) {\n> diff --git a/revision.h b/revision.h\n> index fb74492..21e4d9d 100644\n> --- a/revision.h\n> +++ b/revision.h\n> @@ -84,7 +84,7 @@ struct rev_info {\n>        unsigned int    abbrev;\n>        enum cmit_fmt   commit_format;\n>        struct log_info *loginfo;\n> -       int             nr, total;\n> +       int             nr, total, num_width;\n>        const char      *mime_boundary;\n>        const char      *patch_suffix;\n>        int             numbered_files;\n>\n\nwhy carry around a piece of information that is only used in one place\nand is not expensive to calculate? how about a middle-ground such as:\n\ndiff --git a/log-tree.c b/log-tree.c\nindex 6f73c17..4888518 100644\n--- a/log-tree.c\n+++ b/log-tree.c\n@@ -158,14 +158,11 @@ static void append_signoff(struct strbuf *sb,\nconst char *signoff)\n        strbuf_addch(sb, '\\n');\n }\n\n-static unsigned int digits_in_number(unsigned int number)\n+static int digits_in_number(int number)\n {\n-       unsigned int i = 10, result = 1;\n-       while (i <= number) {\n-               i *= 10;\n-               result++;\n-       }\n-       return result;\n+  static char num_buf[64];\n+  sprintf(num_buf, \"%u\", number);\n+  return (int)strlen(num_buf);\n }\n\n static int has_non_ascii(const char *s)\n"},{"id":"120110","messageId":"200908100724.53345.chriscool@tuxfamily.org","threadId":"20491","inReplyTo":"40aa078e0908090525h7b4d6efeh658e2edcfbe16c7e@mail.gmail.com","subject":"Re: [PATCH] fix potential infinite loop given large unsigned integer","fromName":"Christian Couder","fromEmail":"chriscool@tuxfamily.org","sentAt":"2009-08-10T05:24:52Z","receivedAt":"2009-08-10T05:24:52Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Sunday 09 August 2009, Erik Faye-Lund wrote:\n> On Sun, Aug 9, 2009 at 9:38 AM, Junio C Hamano<gitster@pobox.com> wrote:\n> > +               static char num_buf[64];\n> >                rev.total = total + start_number - 1;\n> > +               sprintf(num_buf, \"%d\", rev.total);\n> > +               rev.num_width = strlen(num_buf);\n>\n> how about\n> rev.num_width = (int)log10((double)rev.total) + 1;\n>\n> hm?\n>\n> log10() appears to be C99, but can be emulated on earlier C-versions by\n> doing #define log10(x) (log(x) / log(10.0))\n\nThat would mean linking with -lm?\n\nRegards,\nChristian.\n"},{"id":"120140","messageId":"40aa078e0908100412l3c2afd1bnda9b10aaf1de383f@mail.gmail.com","threadId":"20491","inReplyTo":"200908100724.53345.chriscool@tuxfamily.org","subject":"Re: [PATCH] fix potential infinite loop given large unsigned integer","fromName":"Erik Faye-Lund","fromEmail":"kusmabite@googlemail.com","sentAt":"2009-08-10T11:12:02Z","receivedAt":"2009-08-10T11:12:02Z","isPatch":true,"sender":{"key":"kusmabite@gmail.com","avatar":"https://avatars.githubusercontent.com/u/47073?v=4"},"body":"On Mon, Aug 10, 2009 at 7:24 AM, Christian\nCouder<chriscool@tuxfamily.org> wrote:\n>> log10() appears to be C99, but can be emulated on earlier C-versions by\n>> doing #define log10(x) (log(x) / log(10.0))\n>\n> That would mean linking with -lm?\n\nI guess so. Are we currently trying to avoid linking to the math-parts of libc?\n\n-- \nErik \"kusma\" Faye-Lund\nkusmabite@gmail.com\n(+47) 986 59 656\n"},{"id":"120145","messageId":"alpine.DEB.1.00.0908101421340.8324@intel-tinevez-2-302","threadId":"20491","inReplyTo":"40aa078e0908100412l3c2afd1bnda9b10aaf1de383f@mail.gmail.com","subject":"Re: [PATCH] fix potential infinite loop given large unsigned integer","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-08-10T12:24:37Z","receivedAt":"2009-08-10T12:24:37Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Mon, 10 Aug 2009, Erik Faye-Lund wrote:\n\n> On Mon, Aug 10, 2009 at 7:24 AM, Christian\n> Couder<chriscool@tuxfamily.org> wrote:\n> >> log10() appears to be C99, but can be emulated on earlier C-versions by\n> >> doing #define log10(x) (log(x) / log(10.0))\n> >\n> > That would mean linking with -lm?\n> \n> I guess so. Are we currently trying to avoid linking to the math-parts \n> of libc?\n\nYes.\n\nI guess we could fix the overflow thing very easily, though:\n\nstatic unsigned int digits_of_number(unsigned int number) {\n\tunsigned int result;\n\tfor (result = 1; number; number /= 10, result++)\n\t\t; /* do nothing */\n\treturn result;\n}\n\nCiao,\nDscho\n"},{"id":"120182","messageId":"a3f15ee60908100914n6d9e11fbk77a90f5619b9a860@mail.gmail.com","threadId":"20491","inReplyTo":"alpine.DEB.1.00.0908101421340.8324@intel-tinevez-2-302","subject":"Re: [PATCH] fix potential infinite loop given large unsigned integer","fromName":"Ryan Flynn","fromEmail":"parseerror@gmail.com","sentAt":"2009-08-10T16:14:43Z","receivedAt":"2009-08-10T16:14:43Z","isPatch":true,"sender":{"key":"parseerror@gmail.com","avatar":"https://gravatar.com/avatar/2dc363300e09c898bd11688dcbe703e82e0102e810b93bd96d6287d32d26c4c0?d=mp&s=160"},"body":"On Mon, Aug 10, 2009 at 8:24 AM, Johannes\nSchindelin<Johannes.Schindelin@gmx.de> wrote:\n> Hi,\n>\n> On Mon, 10 Aug 2009, Erik Faye-Lund wrote:\n>\n>> On Mon, Aug 10, 2009 at 7:24 AM, Christian\n>> Couder<chriscool@tuxfamily.org> wrote:\n>> >> log10() appears to be C99, but can be emulated on earlier C-versions by\n>> >> doing #define log10(x) (log(x) / log(10.0))\n>> >\n>> > That would mean linking with -lm?\n>>\n>> I guess so. Are we currently trying to avoid linking to the math-parts\n>> of libc?\n>\n> Yes.\n>\n> I guess we could fix the overflow thing very easily, though:\n>\n> static unsigned int digits_of_number(unsigned int number) {\n>        unsigned int result;\n>        for (result = 1; number; number /= 10, result++)\n>                ; /* do nothing */\n>        return result;\n> }\n>\n> Ciao,\n> Dscho\n>\n>\n\nthat is equivalent to the original patch, yes.\n"},{"id":"120183","messageId":"a3f15ee60908100917k2a2d6de7ndd5e4ddd1d926cc3@mail.gmail.com","threadId":"20491","inReplyTo":"alpine.DEB.1.00.0908101421340.8324@intel-tinevez-2-302","subject":"Re: [PATCH] fix potential infinite loop given large unsigned integer","fromName":"Ryan Flynn","fromEmail":"parseerror@gmail.com","sentAt":"2009-08-10T16:17:40Z","receivedAt":"2009-08-10T16:17:40Z","isPatch":true,"sender":{"key":"parseerror@gmail.com","avatar":"https://gravatar.com/avatar/2dc363300e09c898bd11688dcbe703e82e0102e810b93bd96d6287d32d26c4c0?d=mp&s=160"},"body":"On Mon, Aug 10, 2009 at 8:24 AM, Johannes\nSchindelin<Johannes.Schindelin@gmx.de> wrote:\n> Hi,\n>\n> On Mon, 10 Aug 2009, Erik Faye-Lund wrote:\n>\n>> On Mon, Aug 10, 2009 at 7:24 AM, Christian\n>> Couder<chriscool@tuxfamily.org> wrote:\n>> >> log10() appears to be C99, but can be emulated on earlier C-versions by\n>> >> doing #define log10(x) (log(x) / log(10.0))\n>> >\n>> > That would mean linking with -lm?\n>>\n>> I guess so. Are we currently trying to avoid linking to the math-parts\n>> of libc?\n>\n> Yes.\n>\n> I guess we could fix the overflow thing very easily, though:\n>\n> static unsigned int digits_of_number(unsigned int number) {\n>        unsigned int result;\n>        for (result = 1; number; number /= 10, result++)\n>                ; /* do nothing */\n>        return result;\n> }\n>\n> Ciao,\n> Dscho\n>\n>\n\nwhoops, actually yours: digits_of_number(1) -> 2\n"},{"id":"120194","messageId":"alpine.DEB.1.00.0908101850570.8324@intel-tinevez-2-302","threadId":"20491","inReplyTo":"a3f15ee60908100917k2a2d6de7ndd5e4ddd1d926cc3@mail.gmail.com","subject":"Re: [PATCH] fix potential infinite loop given large unsigned integer","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-08-10T16:53:34Z","receivedAt":"2009-08-10T16:53:34Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\n[please cull the quoted text to what you are actually replying to.  \nThanks]\n\nOn Mon, 10 Aug 2009, Ryan Flynn wrote:\n\n> On Mon, Aug 10, 2009 at 8:24 AM, Johannes\n> Schindelin<Johannes.Schindelin@gmx.de> wrote:\n> >\n> > static unsigned int digits_of_number(unsigned int number) {\n> >     unsigned int result;\n> >     for (result = 1; number; number /= 10, result++)\n> >         ; /* do nothing */\n> >     return result;\n> > }\n> \n> whoops, actually yours: digits_of_number(1) -> 2\n\nstatic unsigned int digits(unsigned int number)\n{\n        unsigned int result;\n        for (result = 1; (number /= 10); result++)\n                ; /* do nothing */\n        return result;\n}\n\nI'm sorry, I forgot the \"something like this\" in my mail.\n\nThis version is actually tested.\n\nIt has non-optimal runtime, but then, it does not really matter.\n\nCiao,\nDscho"},{"id":"120202","messageId":"alpine.LSU.2.00.0908101914470.14039@hermes-2.csi.cam.ac.uk","threadId":"20491","inReplyTo":"7v3a81a13z.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] fix potential infinite loop given large unsigned integer","fromName":"Tony Finch","fromEmail":"dot@dotat.at","sentAt":"2009-08-10T18:19:12Z","receivedAt":"2009-08-10T18:19:12Z","isPatch":true,"sender":{"key":"dot@dotat.at","avatar":"https://avatars.githubusercontent.com/u/68429?v=4"},"body":"On Sun, 9 Aug 2009, Junio C Hamano wrote:\n\n> +\tif (numbered) {\n> +\t\tstatic char num_buf[64];\n>  \t\trev.total = total + start_number - 1;\n> +\t\tsprintf(num_buf, \"%d\", rev.total);\n> +\t\trev.num_width = strlen(num_buf);\n> +\t}\n\nwhy not\n\n\tif (numbered) {\n\t\trev.total = total + start_number - 1;\n\t\trev.num_width = snprintf(NULL, 0, \"%d\", rev.total);\n\t}\n\n?\n\nTony.\n-- \nf.anthony.n.finch  <dot@dotat.at>  http://dotat.at/\nGERMAN BIGHT HUMBER: SOUTHWEST 5 TO 7. MODERATE OR ROUGH. SQUALLY SHOWERS.\nMODERATE OR GOOD.\n"},{"id":"120212","messageId":"20090811005517.GB32235@unpythonic.net","threadId":"20491","inReplyTo":"40aa078e0908090525h7b4d6efeh658e2edcfbe16c7e@mail.gmail.com","subject":"Re: [PATCH] fix potential infinite loop given large unsigned integer","fromName":"Jeff Epler","fromEmail":"jepler@unpythonic.net","sentAt":"2009-08-11T00:55:17Z","receivedAt":"2009-08-11T00:55:17Z","isPatch":true,"sender":{"key":"jepler@unpythonic.net","avatar":"https://avatars.githubusercontent.com/u/1517291?v=4"},"body":"On Sun, Aug 09, 2009 at 02:25:40PM +0200, Erik Faye-Lund wrote:\n> log10() appears to be C99, but can be emulated on earlier C-versions by doing\n> #define log10(x) (log(x) / log(10.0))\n\nI don't think you'll like the results of this very much.\n    #include <math.h>\n    #include <stdio.h>\n\n    int main(void) {\n        double n=1;\n        int i, j;\n        for(i=0; i<10; i++, n*=10) {\n            j = (int)(log(n)/log(10));\n            if(i != j) printf(\"%d %d\\n\", i, (int)j);\n        }\n        return 0;\n    }\n\n(on my system, 3 of the 10 tested cases give the wrong answer due to\nrounding)\n\nFor a tour of some of the difficulties of implementing log10,\n    http://www.cs.berkeley.edu/~wkahan/LOG10HAF.TXT\n\nJeff\n"}]}