groff-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[groff] 27/29: [tbl]: Handle `\R` sequences in text blocks robustly.


From: G. Branden Robinson
Subject: [groff] 27/29: [tbl]: Handle `\R` sequences in text blocks robustly.
Date: Tue, 26 Apr 2022 06:40:19 -0400 (EDT)

gbranden pushed a commit to branch master
in repository groff.

commit 4f4b79b8aa0f044a3b2e6a97c8e7dd745b5eead9
Author: G. Branden Robinson <g.branden.robinson@gmail.com>
AuthorDate: Tue Apr 26 18:04:32 2022 +1000

    [tbl]: Handle `\R` sequences in text blocks robustly.
    
    * src/preproc/tbl/table.cpp (table::add_entry): Fix SEGV when repeating
      glyph table entry syntax (`\Rx`) used in a text block.  Lift
      extraction of entry string to be done unconditionally, rather than in
      5 different special cases.  This frees us up to rewrite the entry if
      necessary, changing '\R' to '\&' inside a text block.  Recast
      diagnostic to describe the problem clearly--"bad repeated character"
      suggests that something is wrong with the "argument" to `\R`, when
      really the problem is the _context_.
    
    Fixes <http://savannah.gnu.org/bugs/?62366>.
---
 ChangeLog                 | 16 ++++++++++++++++
 src/preproc/tbl/table.cpp | 26 ++++++++++++--------------
 2 files changed, 28 insertions(+), 14 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index ba4cf219..236dd47a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -6,6 +6,22 @@
        do-not-segv-when-backslash-R-in-text-block.sh: Do it.
        * src/preproc/tbl/tbl.am (tbl_TESTS): Run test.
 
+2022-04-26  G. Branden Robinson <g.branden.robinson@gmail.com>
+
+       [tbl]: Handle `\R` sequences in text blocks robustly.
+
+       * src/preproc/tbl/table.cpp (table::add_entry): Fix SEGV when
+       repeating glyph table entry syntax (`\Rx`) used in a text block.
+       Lift extraction of entry string to be done unconditionally,
+       rather than in 5 different special cases.  This frees us up to
+       rewrite the entry if necessary, changing '\R' to '\&' inside a
+       text block.  Recast diagnostic to describe the problem
+       clearly--"bad repeated character" suggests that something is
+       wrong with the "argument" to `\R`, when really the problem is
+       the _context_.
+
+       Fixes <http://savannah.gnu.org/bugs/?62366>.
+
 2022-04-26  G. Branden Robinson <g.branden.robinson@gmail.com>
 
        * src/libs/libgroff/string.cpp (string::extract): Check return
diff --git a/src/preproc/tbl/table.cpp b/src/preproc/tbl/table.cpp
index 66a1c2b5..18cee1e9 100644
--- a/src/preproc/tbl/table.cpp
+++ b/src/preproc/tbl/table.cpp
@@ -1508,6 +1508,18 @@ void table::add_entry(int r, int c, const string &str,
 {
   allocate(r);
   table_entry *e = 0;
+  char *s = str.extract();
+  if (str.search('\n') >= 0) {
+    bool was_changed = false;
+    for (int i = 0; s[i] != '\0'; i++)
+      if ((i > 0) && (s[(i - 1)] == '\\') && (s[i] == 'R')) {
+       s[i] = '&';
+       was_changed = true;
+      }
+    if (was_changed)
+      error_with_file_and_line(fn, ln, "repeating a glyph with '\\R'"
+                              " is not allowed in a text block");
+  }
   if (str == "\\_") {
     e = new short_line_entry(this, f);
   }
@@ -1546,17 +1558,8 @@ void table::add_entry(int r, int c, const string &str,
     else
       do_vspan(r, c);
   }
-  else if (str.length() > 2 && str[0] == '\\' && str[1] == 'R') {
-    if (str.search('\n') >= 0)
-      error_with_file_and_line(fn, ln, "bad repeated character");
-    else {
-      char *s = str.substring(2, str.length() - 2).extract();
-      e = new repeated_char_entry(this, f, s);
-    }
-  }
   else {
     int is_block = str.search('\n') >= 0;
-    char *s;
     switch (f->type) {
     case FORMAT_SPAN:
       assert(str.empty());
@@ -1564,7 +1567,6 @@ void table::add_entry(int r, int c, const string &str,
       break;
     case FORMAT_LEFT:
       if (!str.empty()) {
-       s = str.extract();
        if (is_block)
          e = new left_block_entry(this, f, s);
        else
@@ -1575,7 +1577,6 @@ void table::add_entry(int r, int c, const string &str,
       break;
     case FORMAT_CENTER:
       if (!str.empty()) {
-       s = str.extract();
        if (is_block)
          e = new center_block_entry(this, f, s);
        else
@@ -1586,7 +1587,6 @@ void table::add_entry(int r, int c, const string &str,
       break;
     case FORMAT_RIGHT:
       if (!str.empty()) {
-       s = str.extract();
        if (is_block)
          e = new right_block_entry(this, f, s);
        else
@@ -1597,7 +1597,6 @@ void table::add_entry(int r, int c, const string &str,
       break;
     case FORMAT_NUMERIC:
       if (!str.empty()) {
-       s = str.extract();
        if (is_block) {
          error_with_file_and_line(fn, ln, "can't have numeric text block");
          e = new left_block_entry(this, f, s);
@@ -1615,7 +1614,6 @@ void table::add_entry(int r, int c, const string &str,
       break;
     case FORMAT_ALPHABETIC:
       if (!str.empty()) {
-       s = str.extract();
        if (is_block)
          e = new alphabetic_block_entry(this, f, s);
        else



reply via email to

[Prev in Thread] Current Thread [Next in Thread]