[tex-k] [PATCH 06/10] weave: Prevent get_line() when parsing module name

Benjamin Gray bengray178 at gmail.com
Sun Mar 9 01:47:16 CET 2025


WEAVE handles inline Pascal in module names by appending the inline
Pascal text to the buffer, fences it with '|', and calls
output_Pascal(). The leading '|' is just aesthetic, but the trailing '|'
is important to prevent get_next() from loading the next source line
when the module name text ends.

However it is possible to trick WEAVE into ignoring the terminating '|',
such as with an unterminated verbatim command. This causes get_next() to
call get_line(), which can lead to weird behaviour including segfault.
An example of a segfaulting program is as follows:

    @ @<|@=
    @    @
    @<  |@=   @

A related weird behaviour is that loc can start at limit+3, which skips
the sentinel value if verbatim scanning and will continue unbounded.

To address the problem robustly, make it so that when get_line() is
called it detects if a module name is being parsed and, if so, print an
error message and reset the location to the '|' at the end of the line.
---
 texk/web2c/weave.ch | 54 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)

diff --git a/texk/web2c/weave.ch b/texk/web2c/weave.ch
index 9428be4bfd..a3b3d05a62 100644
--- a/texk/web2c/weave.ch
+++ b/texk/web2c/weave.ch
@@ -323,6 +323,36 @@ begin if no_xref then return;
 if (reserved(p)or(byte_start[p]+1=byte_start[p+ww]))and
 @z
 
+ at x [9.82] l.1448 - Guard against get_line() when parsing a module name
+ at p procedure get_line; {inputs the next line}
+label restart;
+begin restart:if changing then
+  @<Read from |change_file| and maybe turn off |changing|@>;
+if not changing then
+  begin @<Read from |web_file| and maybe turn on |changing|@>;
+  if changing then goto restart;
+  end;
+loc:=0; buffer[limit]:=" ";
+end;
+ at y
+ at p procedure get_line; {inputs the next line}
+label restart;
+begin
+  if in_module_name<>0 then begin
+    err_print('! Call to get_line when parsing a module name');
+    loc:=limit; {Reset to the |'|'| at the end of the line}
+  end else
+begin restart:if changing then
+  @<Read from |change_file| and maybe turn off |changing|@>;
+if not changing then
+  begin @<Read from |web_file| and maybe turn on |changing|@>;
+  if changing then goto restart;
+  end;
+loc:=0; buffer[limit]:=" ";
+end;
+end;
+ at z
+
 @x [12.124] l.2199
 `\.{\\input webmac}'.
 @.\\input webmac@>
@@ -529,6 +559,30 @@ until_like: begin @<Append \(|term...@>;
 @<Append \(|termin...@>=
 @z
 
+ at x [17.214] l.4161 - Guard against get_line() while parsing module name
+@ @<Output the text...@>=
+ at y
+
+@ The module name Pascal parser re-uses the buffer and |get_next|
+infrastructure. However we don't want |get_next| to cause the next source line
+to be read with |get_line|, so we set a flag to trigger an error and recover if
+this happens.
+
+@<Globals...@>=
+@!in_module_name:integer;
+
+@ @<Set init...@>=
+@!in_module_name:=0;
+
+@ @<Output the text...@>=
+ at z
+
+ at x [17.214] l.4170 - Guard against get_line() while parsing module name
+    buffer[limit]:="|"; output_Pascal;
+ at y
+    buffer[limit]:="|"; in_module_name:=1; output_Pascal; in_module_name:=0;
+ at z
+
 @x [19.239] l.4537 - omit index and module names if no_xref set
 @<Phase III: Output the cross-reference index@>=
 @y
-- 
2.48.1



More information about the tex-k mailing list.