gbranden pushed a commit to branch master
in repository groff.
commit fc727f4435e1ab290870ee7951132a66bb148b5d
Author: G. Branden Robinson <[email protected]>
AuthorDate: Thu Aug 1 16:45:35 2024 -0500
[troff]: Validate `hcode` request arguments more.
* src/roff/troff/input.cpp (set_hyphenation_code): Do more input
validation of `hcode` request arguments. Handle case where an
argument is an escape sequence (but not a special character) ourselves
instead of delegating it to `token::get_char()`. Throw errors (and
stop processing arguments) when (1) the destination character is a
numeral; (2) the destination character is a (non-special-character)
escape sequence; (3) the source character is a numeral; or (4) the
source character is a (non-special-character) escape sequence.
* doc/groff.texi.in (Manipulating Hyphenation) <hcode>:
* man/groff_diff.7.man (New requests) <hcode>: Document that the request
aborts processing its arguments upon encountering an invalid one.
Continues <https://savannah.gnu.org/bugs/?66040>. Thanks to Dave Kemper
for further discussion.
$ nl hcode.groff
1 .hcode
2 .hcode \:
3 .hcode a
4 .hcode 0 b
5 .hcode c\:
6 .hcode \['A] \['a]
7 .hcode d 0
8 .hcode eE
9 .hcode f F
10 .hcode g G\" This is my comment.
11 .hcode \['i] i
12 .hcode \['o] \['o]
13 .hcode \['u] u
14 .hcode \['U] \['u]
$ ./build/test-groff -T utf8 -ww hcode.groff
troff:hcode.groff:1: warning: hyphenation code configuration request
expects arguments
troff:hcode.groff:2: error: expected ordinary or special character, got an
escaped ':'
troff:hcode.groff:3: error: hyphenation codes must be specified in pairs
troff:hcode.groff:4: error: cannot apply a hyphenation code to a numeral
troff:hcode.groff:5: error: expected ordinary or special character, got an
escaped ':'
troff:hcode.groff:6: error: second member of hyphenation code pair must be
an ordinary character
troff:hcode.groff:7: error: cannot use the hyphenation code of a numeral
troff:hcode.groff:12: error: second member of hyphenation code pair must be
an ordinary character
troff:hcode.groff:14: error: second member of hyphenation code pair must be
an ordinary character
---
ChangeLog | 20 ++++++++++++++++++
doc/groff.texi.in | 3 ++-
man/groff_diff.7.man | 4 ++++
src/roff/troff/input.cpp | 53 ++++++++++++++++++++++++++++++------------------
4 files changed, 59 insertions(+), 21 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index b77e4d432..5f117ac24 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2024-08-01 G. Branden Robinson <[email protected]>
+
+ * src/roff/troff/input.cpp (set_hyphenation_code): Do more input
+ validation of `hcode` request arguments. Handle case where an
+ argument is an escape sequence (but not a special character)
+ ourselves instead of delegating it to `token::get_char()`.
+ Throw errors (and stop processing arguments) when {1} the
+ destination character is a numeral; {2} the destination
+ character is a (non-special-character) escape sequence; {3} the
+ source character is a numeral; or {4} the source character is a
+ {non-special-character} escape sequence.
+
+ * doc/groff.texi.in (Manipulating Hyphenation) <hcode>:
+ * man/groff_diff.7.man (New requests) <hcode>: Document that the
+ request aborts processing its arguments upon encountering an
+ invalid one.
+
+ Continues <https://savannah.gnu.org/bugs/?66040>. Thanks to
+ Dave Kemper for further discussion.
+
2024-08-01 G. Branden Robinson <[email protected]>
* doc/groff.texi.in (Manipulating Hyphenation) <hcode>:
diff --git a/doc/groff.texi.in b/doc/groff.texi.in
index bbf35d3c4..f77025250 100644
--- a/doc/groff.texi.in
+++ b/doc/groff.texi.in
@@ -8988,7 +8988,8 @@ that of @var{src1}, and so on. @var{dst1} must be an
ordinary character
ordinary character (other than a numeral). Assigning the code of an
ordinary character code to itself effectively creates a unique
hyphenation code (which can then be copied to others). @code{hcode}
-ignores spaces between arguments.
+ignores spaces between arguments. If any argument is invalid,
+@code{hcode} reports an error and stops reading them.
For example, the following @code{hcode} requests are necessary to assign
hyphenation codes to the letters @samp{�������}, needed for German.
diff --git a/man/groff_diff.7.man b/man/groff_diff.7.man
index e3ec772f7..32f4dc0c3 100644
--- a/man/groff_diff.7.man
+++ b/man/groff_diff.7.man
@@ -2628,6 +2628,10 @@ effectively creates a unique hyphenation code
.B hcode
ignores spaces between arguments.
.
+If any argument is invalid,
+.B hcode
+reports an error and stops reading them.
+.
.
.IP
For automatic hyphenation to work,
diff --git a/src/roff/troff/input.cpp b/src/roff/troff/input.cpp
index 615cd3820..c5eaa52de 100644
--- a/src/roff/troff/input.cpp
+++ b/src/roff/troff/input.cpp
@@ -7284,37 +7284,50 @@ static void set_hyphenation_codes()
return;
}
while (!tok.is_newline() && !tok.is_eof()) {
- charinfo *ci = tok.get_char(true /* required */);
- // If we got back some nonsense like a non-character escape
- // sequence, get_char() will have diagnosed it.
- if (0 /* nullptr */ == ci)
+ unsigned char cdst = tok.ch();
+ if (csdigit(cdst)) {
+ error("cannot apply a hyphenation code to a numeral");
break;
+ }
+ charinfo *cidst = tok.get_char();
+ if (0 == cdst) { // destination character is special
+ if (0 /* nullptr */ == cidst) {
+ error("expected ordinary or special character, got %1",
+ tok.description());
+ break;
+ }
+ }
tok.next();
tok.skip();
if (tok.is_newline() || tok.is_eof()) {
error("hyphenation codes must be specified in pairs");
break;
}
- charinfo *ci2 = tok.get_char(true /* required */);
- unsigned char c = tok.ch();
- if (0 == c) {
- if (0 /* nullptr */ == ci2)
- break;
- if (0 == ci2->get_hyphenation_code()) {
- error("second member of hyphenation code pair must be an"
- " ordinary character");
+ unsigned char csrc = tok.ch();
+ if (csdigit(csrc)) {
+ error("cannot use the hyphenation code of a numeral");
+ break;
+ }
+ unsigned char new_code = 0; // TODO: int
+ charinfo *cisrc = tok.get_char();
+ if (csrc != 0)
+ new_code = csrc;
+ else {
+ if (0 /* nullptr */ == cisrc) {
+ error("expected ordinary or special character, got %1",
+ tok.description());
break;
}
- }
- // TODO: What if you want to unset a hyphenation code? Accept 0?
- if (csdigit(c)) {
- error("hyphenation code cannot be digit");
+ // source character is special
+ error("second member of hyphenation code pair must be an"
+ " ordinary character");
break;
+ new_code = cisrc->get_hyphenation_code();
}
- ci->set_hyphenation_code(c);
- if (ci->get_translation()
- && ci->get_translation()->get_translation_input())
- ci->get_translation()->set_hyphenation_code(c);
+ cidst->set_hyphenation_code(new_code);
+ if (cidst->get_translation()
+ && cidst->get_translation()->get_translation_input())
+ cidst->get_translation()->set_hyphenation_code(new_code);
tok.next();
tok.skip();
}
_______________________________________________
Groff-commit mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/groff-commit