Skip to content

Commit

Permalink
Diagnose error if macro expansion makes a line too long for its buffer
Browse files Browse the repository at this point in the history
  • Loading branch information
PhilipHazel committed Aug 11, 2024
1 parent 84cc672 commit a690304
Show file tree
Hide file tree
Showing 12 changed files with 59 additions and 19 deletions.
7 changes: 7 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
ChangeLog file for xfpt
-----------------------

Release 1.01 XX-XXX-2024
------------------------

1. Diagnose an error when inserting an inline macro would overflow a line
buffer.


Release 1.00 08-March-2023
--------------------------

Expand Down
9 changes: 7 additions & 2 deletions src/dot.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* xfpt - Simple ASCII->Docbook processor *
*************************************************/

/* Copyright (c) University of Cambridge, 2023 */
/* Copyright (c) University of Cambridge, 2024 */
/* Written by Philip Hazel, started in 2006 */

/* This module contains code for processing a line that starts with a dot. */
Expand Down Expand Up @@ -482,6 +482,7 @@ while (*p != 0)
*pp = as;
pp = &(as->next);
as->string = misc_readitem(p, NULL, &length, NULL, 0);
as->length = length;
p += length;
}

Expand All @@ -503,7 +504,9 @@ for (;;)
as->next = NULL;
*pp = as;
pp = &(as->next);
as->string = misc_copystring(line, Ustrlen(line));
length = Ustrlen(line);
as->string = misc_copystring(line, length);
as->length = length;
}

/* If there aren't any replacement lines, fake up a comment so that there's
Expand All @@ -514,6 +517,7 @@ if (md->lines == NULL)
md->lines = misc_malloc(sizeof(argstr));
md->lines->next = NULL;
md->lines->string = misc_copystring(US". Dummy line\n", 13);
md->lines->length = 13;
}
}

Expand Down Expand Up @@ -913,6 +917,7 @@ while (*p != 0)
*pp = as;
pp = &(as->next);
as->string = misc_readitem(p, NULL, &length, NULL, 0);
as->length = length;
p += length;
}
}
Expand Down
7 changes: 4 additions & 3 deletions src/error.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* xfpt - Simple ASCII->Docbook processor *
*************************************************/

/* Copyright (c) University of Cambridge, 2023 */
/* Copyright (c) University of Cambridge, 2024 */
/* Written by Philip Hazel, started in 2006 */

/* Error handling routines */
Expand Down Expand Up @@ -81,7 +81,8 @@ static error_struct error_data[] = {
/* 30-34 */
{ ec_serious, "bad macro argument substitution: %s follows \"%s\"" },
{ ec_serious, "binary zero in input ignored" },
{ ec_disaster, "input sources too deeply nested" }
{ ec_disaster, "input sources too deeply nested" },
{ ec_disaster, "maximum line length exceeded during macro substitution" }
};

#define error_maxerror (int)(sizeof(error_data)/sizeof(error_struct))
Expand Down Expand Up @@ -151,7 +152,7 @@ else for (int i = from_type_ptr; i >= 0; i--)
{
if (fe != NULL)
{
if (fe->linenumber > 0)
if (fe->linenumber > 0)
(void)fprintf(stderr, " Detected near line %d of %s\n",
fe->linenumber, fe->filename);
fe = fe->prev;
Expand Down
4 changes: 2 additions & 2 deletions src/functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* xfpt - Simple ASCII->Docbook processor *
*************************************************/

/* Copyright (c) University of Cambridge, 2023 */
/* Copyright (c) University of Cambridge, 2024 */
/* Written by Philip Hazel, started in 2006 */

/* This header defines all the global functions. */
Expand All @@ -23,7 +23,7 @@ extern void para_process(uschar *);

extern uschar *read_nextline(void);
extern uschar *read_paragraph(uschar *, int *);
extern void read_process_macroline(uschar *, uschar *);
extern void read_process_macroline(uschar *, uschar *, int);

extern int tree_insertnode(tree_node **, tree_node *);
extern tree_node *tree_search(tree_node *, uschar *);
Expand Down
4 changes: 2 additions & 2 deletions src/globals.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* xfpt - Simple ASCII->Docbook processor *
*************************************************/

/* Copyright (c) University of Cambridge, 2023 */
/* Copyright (c) University of Cambridge, 2024 */
/* Written by Philip Hazel, started in 2006 */

/* Allocate storage and initialize global variables */
Expand All @@ -11,7 +11,7 @@


uschar *xfpt_share = US DATADIR;
uschar *xfpt_version = US "1.00 01-March-2023";
uschar *xfpt_version = US "1.01-DEV 10-August-2024";

tree_node *entities = NULL;

Expand Down
5 changes: 3 additions & 2 deletions src/para.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* xfpt - Simple ASCII->Docbook processor *
*************************************************/

/* Copyright (c) University of Cambridge, 2023 */
/* Copyright (c) University of Cambridge, 2024 */
/* Written by Philip Hazel, started in 2006 */

/* This module contains code for processing a paragraph by looking for flag
Expand Down Expand Up @@ -69,6 +69,7 @@ while (*q != 0 && *q != ')')
*pp = as;
pp = &(as->next);
as->string = misc_readitem(q, US",)", &length, NULL, 0);
as->length = length;
q += length;
if (*q == ',') while (isspace(*(++q)));
}
Expand All @@ -91,7 +92,7 @@ for (;;)
{
uschar buffer[INBUFFSIZE];

read_process_macroline(macrocurrent->nextline->string, buffer);
read_process_macroline(macrocurrent->nextline->string, buffer, INBUFFSIZE);

/* A directive such as .eacharg can skip to the end of the macro if there
is no .endeach. Detect this by looking for a change of macrocurrent value,
Expand Down
27 changes: 21 additions & 6 deletions src/read.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* xfpt - Simple ASCII->Docbook processor *
*************************************************/

/* Copyright (c) University of Cambridge, 2023 */
/* Copyright (c) University of Cambridge, 2024 */
/* Written by Philip Hazel, started in 2006 */

/* This module contains code for reading the input. */
Expand Down Expand Up @@ -30,7 +30,7 @@ Returns: nothing
*/

void
read_process_macroline(uschar *p, uschar *b)
read_process_macroline(uschar *p, uschar *b, int blen)
{
int optend = 0;

Expand All @@ -49,17 +49,23 @@ while (*p != 0)
continue;
}

/* Ensure at least 3 bytes left in the buffer because all cases except an
argument substitution (which does its own test) add no more than two bytes,
and the third is for the terminating zero. */

if (blen < 3) error(33); /* Hard error; does not return. */

/* Until we hit a dollar, just copy verbatim */

if (*p != '$') { *b++ = *p++; continue; }
if (*p != '$') { *b++ = *p++; blen--; continue; }

/* If dollar is at the end of the string, treat as literal. */

if (p[1] == 0) { *b++ = '$'; break; }

/* If the character after $ is another $, insert a literal $. */

if (p[1] == '$') { p++; *b++ = *p++; continue; }
if (p[1] == '$') { p++; *b++ = *p++; blen--; continue; }

/* If the character after $ is +, we are dealing with arguments
relative to macro_arg0 in a ".eacharg" section. Otherwise, we are dealing
Expand All @@ -73,6 +79,7 @@ while (*p != 0)
error(18);
*b++ = '$';
*b++ = *p++;
blen -= 2;
continue;
}
argbase = macro_argbase;
Expand All @@ -90,6 +97,7 @@ while (*p != 0)
else error(17, p[1], "$=");
*b++ = '$';
*b++ = *p++;
blen -= 2;
continue;
}
while (isdigit(*(++p))) argn = argn * 10 + *p - '0';
Expand Down Expand Up @@ -126,6 +134,7 @@ while (*p != 0)
if (*p == 0 || *p == '\n') error(30, "end of line", "$");
else error(17, p[1], "$");
*b++ = *p++;
blen--;
continue;
}
while (isdigit(*(++p))) argn = argn * 10 + *p - '0';
Expand Down Expand Up @@ -161,7 +170,12 @@ while (*p != 0)

/* If we have found an argument, substitute it. */

if (arg != NULL) b += sprintf(CS b, "%s", arg->string);
if (arg != NULL)
{
blen -= arg->length;
if (blen < 1) error(33); /* Hard; does not return */
b += sprintf(CS b, "%s", arg->string);
}
}

*b = 0;
Expand Down Expand Up @@ -294,7 +308,8 @@ for (;;)
}
else
{
read_process_macroline(macrocurrent->nextline->string, inbuffer);
read_process_macroline(macrocurrent->nextline->string, inbuffer,
INBUFFSIZE);
macrocurrent->nextline = macrocurrent->nextline->next;
break;
}
Expand Down
3 changes: 2 additions & 1 deletion src/structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* xfpt - Simple ASCII->Docbook processor *
*************************************************/

/* Copyright (c) University of Cambridge, 2012 */
/* Copyright (c) University of Cambridge, 2024 */
/* Written by Philip Hazel, started in 2006 */

/* This module contains definitions of structures that are used throughout the
Expand Down Expand Up @@ -44,6 +44,7 @@ typedef struct pushstr {
typedef struct argstr {
struct argstr *next;
uschar *string;
int length;
} argstr;

/* Macro definition item */
Expand Down
5 changes: 5 additions & 0 deletions testing/infiles/07
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.macro m1 one
$1
.endmacro
&m1(111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111)

1 change: 1 addition & 0 deletions testing/outfiles/07
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<para>
4 changes: 4 additions & 0 deletions testing/outfiles/07.err
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
** Error: maximum line length exceeded during macro substitution
Processing macro m1
Detected near line 6 of infiles/07
** xfpt abandoned
2 changes: 1 addition & 1 deletion testing/outfiles/cmd.err
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Usage: xfpt [[-]-help]
[-S <share-directory>]
[-v or --version]
[input-file]
xpft version 1.00 01-March-2023
xpft version 1.01-DEV 10-August-2024
Usage: xfpt [[-]-help]
[-o <output-file>]
[-S <share-directory>]
Expand Down

0 comments on commit a690304

Please sign in to comment.