[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[groff] 02/16: [mm]: Validate reference system state and user input.
From: |
G. Branden Robinson |
Subject: |
[groff] 02/16: [mm]: Validate reference system state and user input. |
Date: |
Fri, 25 Aug 2023 14:11:15 -0400 (EDT) |
gbranden pushed a commit to branch master
in repository groff.
commit 7c8143d92af9132107a43f36f2916e06e6ad0aee
Author: G. Branden Robinson <g.branden.robinson@gmail.com>
AuthorDate: Wed Aug 23 12:30:48 2023 -0500
[mm]: Validate reference system state and user input.
* contrib/mm/m.tmac (qrf*validate-identifier): New macro tests argument
for validity as roff identifier, since user input is applied to this
purpose.
(INITR): Throw error if mandatory argument omitted; keeps us
from creating a (likely unwanted) dotfile, ".qrf".
(SETR, GETST, GETHN, GETPN, GETR): Throw error if reference system
macros used without initialization.
(SETR, GETST, GETHN, GETPN): Validate arguments to be used as string
identifiers.
Also fix code style nits:
Annotate logic. Stop uselessly calling `so` with no-break control
character (it doesn't break in the first place). Break long input line.
Use `\$0` in macro diagnostics instead of hard-coding caller. Fix
misleading/unnecessary indentation. Simply control flow since `@error`
does not return.
---
contrib/mm/ChangeLog | 14 ++++++++
contrib/mm/m.tmac | 97 ++++++++++++++++++++++++++++++++++++++--------------
2 files changed, 85 insertions(+), 26 deletions(-)
diff --git a/contrib/mm/ChangeLog b/contrib/mm/ChangeLog
index 7bc9852fd..818a8d96b 100644
--- a/contrib/mm/ChangeLog
+++ b/contrib/mm/ChangeLog
@@ -1,3 +1,17 @@
+2023-08-23 G. Branden Robinson <g.branden.robinson@gmail.com>
+
+ Validate reference system state and user input.
+
+ * m.tmac (qrf*validate-identifier): New macro tests argument for
+ validity as roff identifier, since user input is applied to this
+ purpose.
+ (INITR): Throw error if mandatory argument omitted; keeps us
+ from creating a (likely unwanted) dotfile, ".qrf".
+ (SETR, GETST, GETHN, GETPN, GETR): Throw error if reference
+ system macros used without initialization.
+ (SETR, GETST, GETHN, GETPN): Validate arguments to be used as
+ string identifiers.
+
2023-08-19 G. Branden Robinson <g.branden.robinson@gmail.com>
* m.tmac: Flush displays at end of input even if they cause page
diff --git a/contrib/mm/m.tmac b/contrib/mm/m.tmac
index 531ad13d4..858ef72c9 100644
--- a/contrib/mm/m.tmac
+++ b/contrib/mm/m.tmac
@@ -3253,25 +3253,48 @@ exceeds depth of nested lists (\\n[li*lvl])
.\" This was needed when I discovered that groff was considered unsafe
.\" and groff -U didn't work. It's a workaround like the original
.\" index method, but not in my view elegant enough.
+.
+.\" Store name of the interface macro calling qrf*validate-identifier.
+.\" Re-empty it after use to catch internal logic errors.
+.ds qrf*caller \" empty
+.
+.\" Validate argument as roff identifier.
+.\" qrf*validate-identifier candidate
+.de qrf*validate-identifier
+.if !\\n[.$]=1 .@abort expected an argument, got \\n[.$]
+.if '\\*[qrf*caller]'' .@abort qrf*caller string not initialized
+.if !\A'\\$1' \{
+. ds qref*msg \\*[qrf*caller]: '\\$1' is not a valid roff string\"
+. as qref*msg " name\"
+. @error \\*[qref*msg]
+.\}
+.ds qrf*caller \" empty
+..
.\"
-.\" init reference system
+.\" INITR id
+.\" Initialize reference system. Read/write file id.qrf.
.de INITR
+.if \\n[.$]<1 .@error \\$0: expected an argument
.ds qrf*file \\$1.qrf
-.nr qrf*pass 2
+.nr qrf*pass 2 \" magic number
.if \\n[D]>1 .tm INITR: source \\*[qrf*file]
.ie \\n[Ref] \{\
. tm .\\\\" Rfilename: \\*[qrf*file]
.\}
-.el 'so \\*[qrf*file]
+.el .so \\*[qrf*file]
..
.\"---------------
-.\" set a reference.
+.\" SETR ref-name [string]
+.\" Set (define) a reference ref-name; store auxiliary datum in string.
.de SETR
.if \\n[.$]<1 .@error \\$0: expected 1 or 2 arguments, got \\n[.$]
-.if !r qrf*pass .tm \\$0: no .INITR in this file \" XXX: .@error?
+.if !r qrf*pass .@error \\$0: references uninitialized; call INITR first
+.ds qrf*caller \\$0\"
.if \\n[Ref] \{\
+. qrf*validate-identifier \\$1
. ds qrf*name qrf*ref-\\$1
-. if \\n[D]>2 .tm SETR: ref \\*[qrf*name]=\\*[hd@mark-trimmed],\\n[%]
+. if \\n[D]>2 \
+. tm \\$0: ref \\*[qrf*name]=\\*[hd@mark-trimmed],\\n[%]
. \" heading-number
. ds \\*[qrf*name]-hn \\*[hd@mark-trimmed]
. \" page-number
@@ -3280,56 +3303,78 @@ exceeds depth of nested lists (\\n[li*lvl])
. if \\n[Ref] \{\
. tm .ds \\*[qrf*name]-hn \\*[hd@mark-trimmed]
. tm .ds \\*[qrf*name]-pn \\n[%]
-. if !'\\$2'' .tm .ds \\*[qrf*name]-xx \\$2
+. if \\n[.$]>1 \{\
+. qrf*validate-identifier \\$2
+. tm .ds \\*[qrf*name]-xx \\$2
+. \}
. \}
.\}
..
.\"---------------
-.\" get misc-string
-.\" If two arg -> set var. arg to misc-string.
+.\" Interpolate or retrieve reference ref-name's auxiliary datum.
+.\" GETST ref-name [string]
.de GETST
.if \\n[.$]<1 .@error \\$0: expected 1 or 2 arguments, got \\n[.$]
-.if !r qrf*pass .tm \\$0: no .INITR in this file \" XXX: .@error?
+.if !r qrf*pass .@error \\$0: references uninitialized; call INITR first
+.ds qrf*caller \\$0\"
+.qrf*validate-identifier \\$1
.ds qrf*name qrf*ref-\\$1
-. if d \\*[qrf*name]-xx \{\
-. ie \\n[.$]>1 .ds \\$2 \\*[\\*[qrf*name]-xx]
-. el \\*[\\*[qrf*name]-xx]\c
+.if d \\*[qrf*name]-xx \{\
+. ie \\n[.$]>1 \{\
+. ds qrf*caller \\$0\"
+. qrf*validate-identifier \\$2
+. ds \\$2 \\*[\\*[qrf*name]-xx]
. \}
+. el \\*[\\*[qrf*name]-xx]\c
.\}
..
.\"---------------
-.\" get header-number
-.\" If two arg -> set var. arg to header-number.
+.\" Interpolate or retrieve reference ref-name's heading number.
+.\" GETHN ref-name [string]
.de GETHN
.if \\n[.$]<1 .@error \\$0: expected 1 or 2 arguments, got \\n[.$]
-.if !r qrf*pass .tm \\$0: no .INITR in this file \" XXX: .@error?
+.if !r qrf*pass .@error \\$0: references uninitialized; call INITR first
+.ds qrf*caller \\$0\"
+.qrf*validate-identifier \\$1
.ds qrf*name qrf*ref-\\$1
.if d \\*[qrf*name]-hn \{\
-. ie \\n[.$]>1 .ds \\$2 \\*[\\*[qrf*name]-hn]
+. ie \\n[.$]>1 \{\
+. ds qrf*caller \\$0\"
+. qrf*validate-identifier \\$2
+. ds \\$2 \\*[\\*[qrf*name]-hn]
+. \}
. el \\*[\\*[qrf*name]-hn]\c
.\}
..
.\"---------------
-.\" get page-number
-.\" If two arg -> set var. arg to page-number.
+.\" Interpolate or retrieve reference ref-name's page number.
+.\" GETPN ref-name [string]
.de GETPN
.if \\n[.$]<1 .@error \\$0: expected 1 or 2 arguments, got \\n[.$]
-.if !r qrf*pass .tm \\$0: no .INITR in this file \" XXX: .@error?
+.if !r qrf*pass .@error \\$0: references uninitialized; call INITR first
+.ds qrf*caller \\$0\"
+.qrf*validate-identifier \\$1
.ds qrf*name qrf*ref-\\$1
.if d \\*[qrf*name]-pn \{\
-. ie \\n[.$]>1 .ds \\$2 \\*[\\*[qrf*name]-pn]
+. ie \\n[.$]>1 \{\
+. ds qrf*caller \\$0\"
+. qrf*validate-identifier \\$2
+. ds \\$2 \\*[\\*[qrf*name]-pn]
+. \}
. el \\*[\\*[qrf*name]-pn]\c
.\}
..
.\"----------
+.\" Retrieve and interpolate reference ref-name's heading and page data.
+.\" GETR ref-name
.de GETR
.if \\n[.$]<1 .@error \\$0: expected an argument
-.ie !r qrf*pass .tm \\$0: no .INITR in this file" \" XXX: .@error?
-.el \{\
-. GETHN \\$1 Qrfh
-. GETPN \\$1 Qrfp
+.if !r qrf*pass .@error \\$0: references uninitialized; call INITR first
+.ds qrf*caller \\$0\"
+.qrf*validate-identifier \\$1
+.GETHN \\$1 Qrfh
+.GETPN \\$1 Qrfp
\\*[Qrf]
-.\}
..
.\"########################### module ind ############################
.\"--------------------
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [groff] 02/16: [mm]: Validate reference system state and user input.,
G. Branden Robinson <=