This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "GNU M4 source repository".
http://git.sv.gnu.org/gitweb/?p=m4.git;a=commitdiff;h=43173c1ade54a595a488e750dfba700c89b9fdb8 The branch, master has been updated via 43173c1ade54a595a488e750dfba700c89b9fdb8 (commit) from c152c4f99c322d676f61732c6e28e8b19b56b736 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 43173c1ade54a595a488e750dfba700c89b9fdb8 Author: Eric Blake <[EMAIL PROTECTED]> Date: Sat May 10 09:16:04 2008 -0600 Detect integer overflow when loading frozen file. * src/freeze.c (reload_frozen_state) [GET_NUMBER]: Rewrite to fail immediately on overflow. * tests/freeze.at (loading format 2): Test this. Reported by Jim Meyering. Signed-off-by: Eric Blake <[EMAIL PROTECTED]> ----------------------------------------------------------------------- Summary of changes: ChangeLog | 8 ++++++++ src/freeze.c | 39 ++++++++++++++++++++++----------------- tests/freeze.at | 45 ++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 74 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index 485fede..05234af 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2008-05-10 Eric Blake <[EMAIL PROTECTED]> + + Detect integer overflow when loading frozen file. + * src/freeze.c (reload_frozen_state) [GET_NUMBER]: Rewrite to fail + immediately on overflow. + * tests/freeze.at (loading format 2): Test this. + Reported by Jim Meyering. + 2008-05-08 Eric Blake <[EMAIL PROTECTED]> Stage 23: allow tracing of indirect macro calls. diff --git a/src/freeze.c b/src/freeze.c index 8df64ce..186b69b 100644 --- a/src/freeze.c +++ b/src/freeze.c @@ -382,15 +382,20 @@ reload_frozen_state (m4 *context, const char *name) #define GET_CHARACTER \ (character = getc (file)) -#define GET_NUMBER(Number) \ +#define GET_NUMBER(Number, AllowNeg) \ do \ { \ - (Number) = 0; \ - while (isdigit (character)) \ + unsigned int n = 0; \ + while (isdigit (character) && n <= INT_MAX / 10) \ { \ - (Number) = 10 * (Number) + character - '0'; \ + n = 10 * n + character - '0'; \ GET_CHARACTER; \ } \ + if (((AllowNeg) ? INT_MIN: INT_MAX) < n \ + || isdigit (character)) \ + m4_error (context, EXIT_FAILURE, 0, NULL, \ + _("integer overflow in frozen file")); \ + (Number) = n; \ } \ while (0) @@ -466,7 +471,7 @@ reload_frozen_state (m4 *context, const char *name) GET_DIRECTIVE; VALIDATE ('V'); GET_CHARACTER; - GET_NUMBER (version); + GET_NUMBER (version, false); switch (version) { case 2: @@ -507,10 +512,10 @@ reload_frozen_state (m4 *context, const char *name) /* Get string lengths. */ - GET_NUMBER (number[0]); + GET_NUMBER (number[0], false); VALIDATE (','); GET_CHARACTER; - GET_NUMBER (number[1]); + GET_NUMBER (number[1], false); if (character == ',') { @@ -519,7 +524,7 @@ reload_frozen_state (m4 *context, const char *name) /* 'F' operator accepts an optional third argument for format versions 2 or later. */ GET_CHARACTER; - GET_NUMBER (number[2]); + GET_NUMBER (number[2], false); } else /* 3 argument 'F' operations are invalid for format @@ -578,7 +583,7 @@ ill-formed frozen file, version 2 directive `%c' encountered"), 'M'); } GET_CHARACTER; - GET_NUMBER (number[0]); + GET_NUMBER (number[0], false); VALIDATE ('\n'); GET_STRING (file, string[0], allocated[0], number[0]); VALIDATE ('\n'); @@ -597,7 +602,7 @@ ill-formed frozen file, version 2 directive `%c' encountered"), 'R'); } GET_CHARACTER; - GET_NUMBER (number[0]); + GET_NUMBER (number[0], false); VALIDATE ('\n'); GET_STRING (file, string[0], allocated[0], number[0]); VALIDATE ('\n'); @@ -624,7 +629,7 @@ ill-formed frozen file, version 2 directive `%c' encountered"), 'S'); GET_CHARACTER; syntax = character; GET_CHARACTER; - GET_NUMBER (number[0]); + GET_NUMBER (number[0], false); VALIDATE ('\n'); GET_STRING (file, string[0], allocated[0], number[0]); @@ -652,14 +657,14 @@ ill-formed frozen file, version 2 directive `%c' encountered"), 'S'); { /* Accept a negative diversion number. */ GET_CHARACTER; - GET_NUMBER (number[0]); + GET_NUMBER (number[0], true); number[0] = -number[0]; } else - GET_NUMBER (number[0]); + GET_NUMBER (number[0], false); VALIDATE (','); GET_CHARACTER; - GET_NUMBER (number[1]); + GET_NUMBER (number[1], false); VALIDATE ('\n'); /* Get string contents. */ @@ -709,10 +714,10 @@ ill-formed frozen file, version 2 directive `%c' encountered"), 'S'); /* Get string lengths. */ - GET_NUMBER (number[0]); + GET_NUMBER (number[0], false); VALIDATE (','); GET_CHARACTER; - GET_NUMBER (number[1]); + GET_NUMBER (number[1], false); if (character == ',') { @@ -721,7 +726,7 @@ ill-formed frozen file, version 2 directive `%c' encountered"), 'S'); /* 'T' operator accepts an optional third argument for format versions 2 or later. */ GET_CHARACTER; - GET_NUMBER (number[2]); + GET_NUMBER (number[2], false); } else { diff --git a/tests/freeze.at b/tests/freeze.at index 2a84843..56933b7 100644 --- a/tests/freeze.at +++ b/tests/freeze.at @@ -167,7 +167,8 @@ builtinbuiltingnu # introduced 2007-05-28 and fixed 2007-05-31. D-1,5 12345 -D0,0 +# Zero can be implied +D, # Testing escape sequences T4,5 @@ -201,6 +202,48 @@ AT_CHECK_M4([-R bogus.m4f], [63], [], [[m4: frozen file version 3 greater than max supported of 2 ]]) +dnl Check that V appears. +AT_DATA([bogus.m4f], [[# not really a frozen file +oops +]]) +AT_CHECK_M4([-R bogus.m4f], [1], [], +[[m4: expecting character `V' in frozen file +]]) + +dnl M4_DIVNUM_TEST(number, [out-of-bounds]) +dnl Check for diversion number corner case handling. Simulate freezing with +dnl number as the active diversion, then reload and check that number. If +dnl OUT-OF-BOUNDS, expect reloading to reject the frozen file. +m4_define([M4_DIVNUM_TEST], [ +AT_DATA([frozen.m4f], [[V2 +M2 +m4 +M3 +gnu +F6,6,2 +divnumdivnumm4 +F6,6,2 +divertdivertm4 +F6,6,2 +definedefinem4 +D]$1[,3 +hi + +]]) +AT_CHECK_M4([-R frozen.m4f in.m4], m4_ifval([$2], [1], [0]), +m4_ifval([$2], [], [[$1 +]m4_if(m4_substr([$1], [0], [1]), [-], [], [[hi +]])]), m4_ifval([$2], [[m4: integer overflow in frozen file +]])) +]) + +AT_DATA([in.m4], [[define(d,divnum)divert(0)d +]]) +M4_DIVNUM_TEST([2147483647]) +M4_DIVNUM_TEST([2147483648], [:]) +M4_DIVNUM_TEST([-2147483648]) +M4_DIVNUM_TEST([-2147483649], [:]) + AT_CLEANUP hooks/post-receive -- GNU M4 source repository
