groff-commit
[Top][All Lists]
Advanced

[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 ############################
 .\"--------------------



reply via email to

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