gbranden pushed a commit to branch master
in repository groff.

commit c8edb82517bbeb1e13b957bb985c5b7c80c61dd5
Author: G. Branden Robinson <[email protected]>
AuthorDate: Sat Aug 17 18:00:23 2024 -0500

    [troff]: Fix buglet in escs with newline delims.
    
    * src/roff/troff/input.cpp (do_name_test): Fix buglet in handling of
      newline as delimiter for the `\A`, `\w`, and `\Z` escape sequences.
      An invalid C++ conditional resulted in a newline being interpreted
      both as the delimiter and as an input token, spuriously putting a
      space on the output.  Drop subsequent tautologous conditional: `tok !=
      start_token` will always evaluate true because `tok.is_eof()` is true
      and `start_token` cannot be an EOF.
    
      Before:
    
      $ printf 'foo\A\naz\nbar\n' | groff -a
      <beginning of page>
      foo1 bar
    
      After:
    
      $ printf 'foo\A\naz\nbar\n' | ./build/test-groff -a
      <beginning of page>
      foo1bar
    
    * src/roff/groff/tests/some_escapes_accept_newline_delimiters.sh: Update
      test expectations.
---
 ChangeLog                                          | 27 ++++++++++++++++++++++
 .../some_escapes_accept_newline_delimiters.sh      | 26 +++++++++------------
 src/roff/troff/input.cpp                           | 26 +++++++++------------
 3 files changed, 49 insertions(+), 30 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 2737c68e1..8806ebc8d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,30 @@
+2024-08-17  G. Branden Robinson <[email protected]>
+
+       * src/roff/troff/input.cpp (do_name_test): Fix buglet in
+       handling of newline as delimiter for the `\A`, `\w`, and `\Z`
+       escape sequences.  An invalid C++ conditional resulted
+       in a newline being interpreted both as the delimiter and as an
+       input token, spuriously putting a space on the output.  Drop
+       subsequent tautologous conditional: `tok != start_token` will
+       always evaluate true because `tok.is_eof()` is true and
+       `start_token` cannot be an EOF.
+
+       Before:
+
+       $ printf 'foo\A\naz\nbar\n' | groff -a
+       <beginning of page>
+       foo1 bar
+
+       After:
+
+       $ printf 'foo\A\naz\nbar\n' | ./build/test-groff -a
+       <beginning of page>
+       foo1bar
+
+       * src/roff/groff/tests/\
+       some_escapes_accept_newline_delimiters.sh: Update test
+       expectations.
+
 2024-08-17  G. Branden Robinson <[email protected]>
 
        * src/roff/troff/input.cpp (interpolate_register): Add assertion
diff --git a/src/roff/groff/tests/some_escapes_accept_newline_delimiters.sh 
b/src/roff/groff/tests/some_escapes_accept_newline_delimiters.sh
index 595e486d9..ccc0e826e 100755
--- a/src/roff/groff/tests/some_escapes_accept_newline_delimiters.sh
+++ b/src/roff/groff/tests/some_escapes_accept_newline_delimiters.sh
@@ -43,7 +43,7 @@ test -z "$error" || wail
 
 echo "checking correct handling of newline delimiter to 'A' escape" >&2
 output=$(printf "%s\n" "$input" | "$groff" -Tascii -ww)
-test "$output" = "1 D" || wail
+test "$output" = "1D" || wail
 
 input=".sp
 \b
@@ -86,7 +86,7 @@ test -z "$error" || wail
 
 echo "checking correct handling of newline delimiter to 'w' escape" >&2
 output=$(printf "%s\n" "$input" | "$groff" -Tascii -ww)
-test "$output" = "72 D" || wail
+test "$output" = "72D" || wail
 
 input="\X
 tty: link http://example.com
@@ -101,27 +101,23 @@ echo "checking correct handling of newline delimiter to 
'X' escape" >&2
 output=$(printf "%s\n" "$input" | "$groff" -Tascii -ww -P -c)
 test "$output" = ' D' || wail
 
-input="\Z
-ABC
-D
-.pl 1v>?\n(nlu"
+input='.
+.ec @
+A@Z
+BCD
+E
+.pl 1v>?@n(nlu
+.'
 
 echo "checking that newline is accepted as delimiter to 'Z' escape" >&2
 error=$(printf "%s\n" "$input" | "$groff" -Tascii -ww -z 2>&1)
 test -z "$error" || wail
 
-# This looks really weird but is consistent.  A newline used as a
-# delimiter still gets interpreted as an input line ending.  What we see
-# here is: 'ABC' is formatted, the drawing position is reset to the
-# beginning of the line, a word space (from filling, overstriking 'A')
-# goes on the output, followed by 'D', so it appears as 'ADC'.
-#
-# `printf '\\Z@ABC@\nD\n'` produces the same output.
 echo "checking correct handling of newline delimiter to 'Z' escape" >&2
 output=$(printf "%s\n" "$input" | "$groff" -Tascii -ww \
   | LC_ALL=C od -t c)
-printf "%s\n" "$output" | grep -Eqx '0000000 +A +B +\\b +D +C +\\n *' \
-  || wail
+printf "%s\n" "$output" \
+  | grep -Eqx '0000000 +A +B +\\b +E +C +D +\\n *' || wail
 
 test -z "$fail"
 
diff --git a/src/roff/troff/input.cpp b/src/roff/troff/input.cpp
index aa9c8ea29..84b87a60d 100644
--- a/src/roff/troff/input.cpp
+++ b/src/roff/troff/input.cpp
@@ -1647,11 +1647,10 @@ static int do_name_test()
   bool got_some_char = false;
   for (;;) {
     tok.next();
-    if (tok.is_newline() || tok.is_eof()) {
-      if (tok != start_token)
-       warning(WARN_DELIM, "missing closing delimiter in identifier"
-               " validation escape sequence (got %1)",
-               tok.description());
+    if (tok.is_eof()) {
+      warning(WARN_DELIM, "missing closing delimiter in identifier"
+             " validation escape sequence (got %1)",
+             tok.description());
       // Synthesize an input line ending.
       input_stack::push(make_temp_iterator("\n"));
       break;
@@ -1746,11 +1745,9 @@ static node *do_zero_width()
   start_token.next();
   for (;;) {
     tok.next();
-    if (tok.is_newline() || tok.is_eof()) {
-      if (tok != start_token)
-       warning(WARN_DELIM, "missing closing delimiter in"
-               " zero-width escape sequence (got %1)",
-               tok.description());
+    if (tok.is_eof()) {
+      warning(WARN_DELIM, "missing closing delimiter in zero-width"
+             " escape sequence (got %1)", tok.description());
       // Synthesize an input line ending.
       input_stack::push(make_temp_iterator("\n"));
       break;
@@ -5458,11 +5455,10 @@ static void do_width()
   curenv = &env;
   for (;;) {
     tok.next();
-    if (tok.is_newline() || tok.is_eof()) {
-      if (tok != start_token)
-       warning(WARN_DELIM, "missing closing delimiter in"
-               " width computation escape sequence (got %1)",
-               tok.description());
+    if (tok.is_eof()) {
+      warning(WARN_DELIM, "missing closing delimiter in width"
+             " computation escape sequence (got %1)",
+             tok.description());
       // Synthesize an input line ending.
       input_stack::push(make_temp_iterator("\n"));
       break;

_______________________________________________
Groff-commit mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/groff-commit

Reply via email to