summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Blake <ebb9@byu.net>2008-05-13 06:25:46 -0600
committerEric Blake <ebb9@byu.net>2008-05-13 11:26:33 -0600
commit4fab2788576b9e10374138be453620a05c95c7be (patch)
tree15ed17d5f5b8978fe7aa1a43f6510df90647a0c2
parent43173c1ade54a595a488e750dfba700c89b9fdb8 (diff)
downloadm4-4fab2788576b9e10374138be453620a05c95c7be.tar.gz
Improve error message when frozen file is invalid.
* src/freeze.c (decode_char): Add parameter. Allow \<newline> line continuations. (reload_frozen_state): Track current line. * tests/freeze.at (loading format 1, loading format 2): Update to test this. Signed-off-by: Eric Blake <ebb9@byu.net>
-rw-r--r--ChangeLog9
-rw-r--r--src/freeze.c57
-rw-r--r--tests/freeze.at39
3 files changed, 86 insertions, 19 deletions
diff --git a/ChangeLog b/ChangeLog
index 05234af5..4bee8823 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2008-05-13 Eric Blake <ebb9@byu.net>
+
+ Improve error message when frozen file is invalid.
+ * src/freeze.c (decode_char): Add parameter. Allow \<newline>
+ line continuations.
+ (reload_frozen_state): Track current line.
+ * tests/freeze.at (loading format 1, loading format 2): Update to
+ test this.
+
2008-05-10 Eric Blake <ebb9@byu.net>
Detect integer overflow when loading frozen file.
diff --git a/src/freeze.c b/src/freeze.c
index 186b69b0..897a2460 100644
--- a/src/freeze.c
+++ b/src/freeze.c
@@ -34,7 +34,7 @@ static void produce_symbol_dump (m4 *, FILE *, m4_symbol_table *);
static void *dump_symbol_CB (m4_symbol_table *, const char *,
m4_symbol *, void *);
static void issue_expect_message (m4 *, int);
-static int decode_char (FILE *);
+static int decode_char (m4 *, FILE *, bool *);
/* Dump an ASCII-encoded representation of LEN bytes at MEM to FILE.
@@ -294,13 +294,19 @@ issue_expect_message (m4 *context, int expected)
unrecognized escape sequence. */
static int
-decode_char (FILE *in)
+decode_char (m4 *context, FILE *in, bool *advance_line)
{
int ch = getc (in);
int next;
int value = 0;
- if (ch == '\\')
+ if (*advance_line)
+ {
+ m4_set_current_line (context, m4_get_current_line (context) + 1);
+ *advance_line = false;
+ }
+
+ while (ch == '\\')
{
ch = getc (in);
switch (ch)
@@ -314,6 +320,11 @@ decode_char (FILE *in)
case 'v': return '\v';
case '\\': return '\\';
+ case '\n':
+ ch = getc (in);
+ m4_set_current_line (context, m4_get_current_line (context) + 1);
+ continue;
+
case 'x': case 'X':
next = getc (in);
if (next >= '0' && next <= '9')
@@ -360,6 +371,8 @@ decode_char (FILE *in)
}
}
+ if (ch == '\n')
+ *advance_line = true;
return ch;
}
@@ -378,9 +391,22 @@ reload_frozen_state (m4 *context, const char *name)
char *string[3];
size_t allocated[3];
int number[3] = {0};
-
-#define GET_CHARACTER \
- (character = getc (file))
+ bool advance_line = true;
+
+#define GET_CHARACTER \
+ do \
+ { \
+ if (advance_line) \
+ { \
+ m4_set_current_line (context, \
+ m4_get_current_line (context) + 1); \
+ advance_line = false; \
+ } \
+ character = getc (file); \
+ if (character == '\n') \
+ advance_line = true; \
+ } \
+ while (0)
#define GET_NUMBER(Number, AllowNeg) \
do \
@@ -404,12 +430,14 @@ reload_frozen_state (m4 *context, const char *name)
{ \
size_t len = (StrLen); \
char *p; \
+ int ch; \
CHECK_ALLOCATION ((Buf), (BufSize), len); \
p = (Buf); \
while (len-- > 0) \
{ \
- int ch = (version > 1 ? decode_char (File) \
- : getc (File)); \
+ ch = (version > 1 \
+ ? decode_char (context, File, &advance_line) \
+ : getc (File)); \
if (ch == EOF) \
m4_error (context, EXIT_FAILURE, 0, NULL, \
_("premature end of frozen file")); \
@@ -452,12 +480,19 @@ reload_frozen_state (m4 *context, const char *name)
GET_CHARACTER; \
VALIDATE ('\n'); \
} \
+ else if (character == '\\') \
+ { \
+ GET_CHARACTER; \
+ VALIDATE ('\n'); \
+ continue; \
+ } \
} \
while (character == '\n')
file = m4_path_search (context, name, (char **)NULL);
if (file == NULL)
m4_error (context, EXIT_FAILURE, errno, NULL, _("cannot open `%s'"), name);
+ m4_set_current_file (context, name);
allocated[0] = 100;
string[0] = xcharalloc (allocated[0]);
@@ -773,7 +808,11 @@ ill-formed frozen file, version 2 directive `%c' encountered"), 'T');
free (string[0]);
free (string[1]);
free (string[2]);
- fclose (file);
+ if (ferror (file) || fclose (file) != 0)
+ m4_error (context, EXIT_FAILURE, errno, NULL,
+ _("unable to read frozen state"));
+ m4_set_current_file (context, NULL);
+ m4_set_current_line (context, 0);
#undef GET_STRING
#undef GET_CHARACTER
diff --git a/tests/freeze.at b/tests/freeze.at
index 56933b75..e43af6ce 100644
--- a/tests/freeze.at
+++ b/tests/freeze.at
@@ -138,6 +138,15 @@ bar${1}
[[m4:input.m4:5: Warning: popdef: undefined macro `my_define'
]])
+dnl Test rejection of v2 features in a v1 frozen file
+AT_DATA([bogus.m4f], [[V1
+M2
+m4
+]])
+AT_CHECK_M4([-R bogus.m4f], [1], [],
+[[m4:bogus.m4f:2: ill-formed frozen file, version 2 directive `M' encountered
+]])
+
AT_CLEANUP
@@ -167,6 +176,10 @@ builtinbuiltingnu
# introduced 2007-05-28 and fixed 2007-05-31.
D-1,5
12345
+# Check line continuations.
+D1,3
+a\n\
+b
# Zero can be implied
D,
@@ -193,13 +206,15 @@ AT_CHECK_M4([-R frozen.m4f input.m4], [0],
bar
'7 \
-]])
+a
+b]])
dnl We don't support anything larger than format 2; make sure of that...
-AT_DATA([bogus.m4f], [[V3
+AT_DATA([bogus.m4f], [[# comments aren't continued\
+V3
]])
AT_CHECK_M4([-R bogus.m4f], [63], [],
-[[m4: frozen file version 3 greater than max supported of 2
+[[m4:bogus.m4f:2: frozen file version 3 greater than max supported of 2
]])
dnl Check that V appears.
@@ -207,7 +222,7 @@ AT_DATA([bogus.m4f], [[# not really a frozen file
oops
]])
AT_CHECK_M4([-R bogus.m4f], [1], [],
-[[m4: expecting character `V' in frozen file
+[[m4:bogus.m4f:2: expecting character `V' in frozen file
]])
dnl M4_DIVNUM_TEST(number, [out-of-bounds])
@@ -220,8 +235,12 @@ M2
m4
M3
gnu
+T1,5
+a\n\n\n\n\n
F6,6,2
-divnumdivnumm4
+divnum\
+divnumm4\
+
F6,6,2
divertdivertm4
F6,6,2
@@ -231,16 +250,16 @@ 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
+m4_ifval([$2], [], [m4_bpatsubst([$1], [^0*])
+m4_if(m4_substr([$1], [0], [1]), [-], [], [[hi
+]])]), m4_ifval([$2], [[m4:frozen.m4f:16: 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([02147483647])
+M4_DIVNUM_TEST([02147483648], [:])
M4_DIVNUM_TEST([-2147483648])
M4_DIVNUM_TEST([-2147483649], [:])