commit a91cd457d95e4e6b67adf3d00185598afccfc87d Author: G. Branden Robinson <g.branden.robin...@gmail.com> Date: Thu Sep 26 16:50:58 2024 -0500 [tbl]: Warn on unreliable escape seqs in entries. […] diff --git a/src/preproc/tbl/table.cpp b/src/preproc/tbl/table.cpp index ab6eea7ee..596a854b0 100644 --- a/src/preproc/tbl/table.cpp +++ b/src/preproc/tbl/table.cpp […] @@ -1525,7 +1525,40 @@ void table::add_entry(int r, int c, const string &str, allocate(r); table_entry *e = 0 /* nullptr */; int len = str.length(); + // Diagnose escape sequences that can wreak havoc in generated output. if (len > 1) { + const char *entryptr = str.contents(); + // A comment on a control line or in a text block is okay. + const char *commentptr = strstr(entryptr, "\\\""); […]
Branden, the class string doesn’t null-terminate its buffer. The function strstr expects a null-terminated string. You could use memmem instead of strstr.
$ GROFF_COMMAND_PREFIX= GROFF_BIN_PATH=. ./groff -M doc -M tmac -F font -ww -b -pet -Tps -ms doc/ms.ms >doc/ms.ps ./groff: error: tbl: Segmentation fault (core dumped) $ egdb tbl tbl.core […] Program terminated with signal SIGSEGV, Segmentation fault. #0 0x000000945b47b380 in twobyte_strstr (h=<optimized out>, n=0x91b7c94f82 "\\\"") at /usr/src/lib/libc/string/strstr.c:33 33 for (h++; *h && hw != nw; hw = hw<<8 | *++h); (gdb) bt #0 0x000000945b47b380 in twobyte_strstr (h=<optimized out>, n=0x91b7c94f82 "\\\"") at /usr/src/lib/libc/string/strstr.c:33 #1 _libc_strstr (h=<optimized out>, n=0x91b7c94f82 "\\\"") at /usr/src/lib/libc/string/strstr.c:181 #2 0x00000091b7cb308e in strstr[abi:v160006] ( __s1=0x93ca5dffe0 "\\[rs]*[SN\\-STYLE]", '\337' <repeats 14 times>, <incomplete sequence \337><error: Cannot access memory at address 0x93ca5e0000>, __s2=0x91b7c94f82 "\\\"") at /usr/include/c++/v1/string.h:103 #3 0x00000091b7cabf33 in table::add_entry (this=0x93ca5dcbe0, r=23, c=1, str=..., f=0x93ca5a5348, fn=0x93ca5b1c20 "doc/ms.ms", ln=584) at src/preproc/tbl/table.cpp:1533 #4 0x00000091b7ca330f in process_data (in=..., f=0x93ca5b67c0, opt=0x93ca5b19c0) at src/preproc/tbl/main.cpp:1518 #5 0x00000091b7c9e6bc in process_table (in=...) at src/preproc/tbl/main.cpp:1616 #6 0x00000091b7c9e17e in process_input_file (fp=0x945b5147a0 <__sF>) at src/preproc/tbl/main.cpp:256 #7 0x00000091b7ca3dab in main (argc=1, argv=0x708dbb3a85e8) at src/preproc/tbl/main.cpp:1708 (gdb) l src/preproc/tbl/table.cpp:1533 1528 int len = str.length(); 1529 // Diagnose escape sequences that can wreak havoc in generated output. 1530 if (len > 1) { 1531 const char *entryptr = str.contents(); 1532 // A comment on a control line or in a text block is okay. 1533 const char *commentptr = strstr(entryptr, "\\\""); 1534 if (commentptr != 0 /* nullptr */) { 1535 const char *controlptr = strchr(entryptr, '.'); 1536 if ((controlptr == 0 /* nullptr */) 1537 || (controlptr == entryptr) (gdb)