gbranden pushed a commit to branch master
in repository groff.

commit e64bec590af55c29579ae4990665badc266f63a1
Author: G. Branden Robinson <[email protected]>
AuthorDate: Sat Jul 11 19:26:56 2026 -0500

    [troff]: Fix Savannah #68511.
    
    ...recovering from a botched refactor.
    
    * src/roff/troff/input.cpp (read_any_character): New function reads any
      groff character--ordinary, special, or indexed--from the input stream,
      skipping any spaces.  While a fairly simple task, it can be done
      incorrectly nevertheless.  Multiple request handlers can use this.
      Start...
    
      (set_hyphenation_codes): ...here.  Rearrange "do/while" loop to
      "while" loop.  Advance the input stream after reading the destination
      character in a pair.  Failing to do so was the defect.  Simplify an
      error diagnostic message.  Simplify a conditional code path.
    
    Fixes <https://savannah.gnu.org/bugs/?68511>.  Problem introduced by me
    in commit 994fcce775, 24 May.  Thanks to Dave Kemper for the report.
---
 ChangeLog                | 20 ++++++++++++++++++++
 src/roff/troff/input.cpp | 42 ++++++++++++++++++++++++++----------------
 2 files changed, 46 insertions(+), 16 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index c4f2a1d5f..b628b8a33 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2026-07-11  G. Branden Robinson <[email protected]>
+
+       [troff]: Fix Savannah #68511, recovering from a botched
+       refactor.
+
+       * src/roff/troff/input.cpp (read_any_character): New function
+       reads any groff character--ordinary, special, or indexed--from
+       the input stream, skipping any spaces.  While a fairly simple
+       task, it can be done incorrectly nevertheless.  Multiple request
+       handlers can use this.  Start...
+       (set_hyphenation_codes): ...here.  Rearrange "do/while" loop to
+       "while" loop.  Advance the input stream after reading the
+       destination character in a pair.  Failing to do so was the
+       defect.  Simplify an error diagnostic message.  Simplify a
+       conditional code path.
+
+       Fixes <https://savannah.gnu.org/bugs/?68511>.  Problem
+       introduced by me in commit 994fcce775, 24 May.  Thanks to Dave
+       Kemper for the report.
+
 2026-07-11  G. Branden Robinson <[email protected]>
 
        [groff]: Add unit test for `hcode` request.
diff --git a/src/roff/troff/input.cpp b/src/roff/troff/input.cpp
index bf1da55be..a0ebff94c 100644
--- a/src/roff/troff/input.cpp
+++ b/src/roff/troff/input.cpp
@@ -1169,6 +1169,21 @@ static symbol 
read_crement_and_escape_sequence_parameter(int *incp)
   return symbol(buf);
 }
 
+// Read any groff character--ordinary, special, or indexed, from the
+// input stream, skipping any spaces, returning true if a character is
+// present and false otherwise.
+//
+// Request handlers that don't need their character "arguments"
+// separated by space use this.
+static bool read_any_character() {
+  tok.skip_spaces();
+  bool is_character = tok.is_any_character();
+  if (!is_character && !tok.is_terminator())
+    error("expected ordinary, special, or indexed character, got %1",
+         tok.description());
+  return is_character;
+}
+
 // In copy mode, we don't tokenize normally; characters on the input
 // stream are typically read into the contents of an existing node (like
 // a string or macro definition), or discarded.  A handful of escape
@@ -8903,8 +8918,7 @@ static void set_hyphenation_codes() // .hcode
     skip_line();
     return;
   }
-  tok.skip_spaces();
-  do {
+  while (read_any_character()) {
     unsigned char cdst = tok.ch();
     if (!tok.is_any_character()) {
       error("cannot apply a hyphenation code to %1", tok.description());
@@ -8922,14 +8936,13 @@ static void set_hyphenation_codes() // .hcode
        break;
       }
     }
-    tok.skip_spaces();
-    if (tok.is_newline() || tok.is_eof()) {
-      error("hyphenation codes must be specified in pairs");
-      break;
-    }
-    if (!tok.is_any_character()) {
-      error("cannot copy the hyphenation code of a non-character (%1)",
-           tok.description());
+    tok.next();
+    if (!read_any_character()) {
+      if (tok.is_newline())
+       error("hyphenation codes must be specified in pairs");
+      else
+       error("cannot copy the hyphenation code of %1",
+             tok.description());
       break;
     }
     unsigned char csrc = tok.ch();
@@ -8951,19 +8964,16 @@ static void set_hyphenation_codes() // .hcode
       }
       new_code = cisrc->get_hyphenation_code();
     }
-    else {
+    else if (csrc == cdst)
       // If assigning a ordinary character's hyphenation code to itself,
       // use its character code point as the value.
-      if (csrc == cdst)
-       new_code = tok.ch();
-    }
+      new_code = tok.ch();
     cidst->set_hyphenation_code(new_code);
     if (cidst->get_translation()
        && cidst->get_translation()->is_translatable_as_input())
       cidst->get_translation()->set_hyphenation_code(new_code);
     tok.next();
-    tok.skip_spaces();
-  } while ((!tok.is_newline()) && (!tok.is_eof()));
+  }
   skip_line();
 }
 

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

Reply via email to