]> git.cameronkatri.com Git - mandoc.git/log
mandoc.git
2 years agoimprove the description of header.html and footer.html
Ingo Schwarze [Wed, 6 Jul 2022 15:47:28 +0000 (15:47 +0000)]
improve the description of header.html and footer.html

2 years agoassign the ARIA role "doc-subtitle" to the .Nd element;
Ingo Schwarze [Wed, 6 Jul 2022 15:26:23 +0000 (15:26 +0000)]
assign the ARIA role "doc-subtitle" to the .Nd element;
discussed with Anna Vyalkova <cyber at sysrq dot in>

2 years agoWhile the HTML standard allows multiple <h1> elements in the same
Ingo Schwarze [Wed, 6 Jul 2022 14:34:59 +0000 (14:34 +0000)]
While the HTML standard allows multiple <h1> elements in the same
document, <h1> is intended for top level headers, and most of the
sections in a manual page can hardly be considered top-level.
It is more usual to use <h1> only for the main title of the document
of for the site name.

Consequently, move .Sh/.SH from <h1> to <h2> and .Ss/.SS from <h2>
to <h3>, freeing <h1> for use by header.html in man.cgi(8).

Discussed with Anna Vyalkova <cyber at sysrq dot in>.

2 years agoFinally get rid of the archaic <table> markup for header and footer lines
Ingo Schwarze [Tue, 5 Jul 2022 21:25:29 +0000 (21:25 +0000)]
Finally get rid of the archaic <table> markup for header and footer lines
and use flexbox CSS instead.  Improve accessibility by adding role
and aria-label attributes to these header and footer lines.
Using ideas from both Anna Vyalkova <cyber at sysrq dot in> and myself.

As a welcome side effect, this also resolves the long-standing issue
that the rendering was always 65em wide, requiring horizontal scrolling
when the window was narrower.  Now, rendering nicely adapts to browser
windows of arbitrary narrowness.

2 years agoSomehow, the content of header.html ended up
Ingo Schwarze [Tue, 5 Jul 2022 14:04:25 +0000 (14:04 +0000)]
Somehow, the content of header.html ended up
before and outside the <header> element.
Fix this by moving it into the <header> element where it belongs.
While here, also wrap footer.html in a <footer> element.

2 years agoImprove accessibility of man.cgi(8) in various respects,
Ingo Schwarze [Mon, 4 Jul 2022 16:20:42 +0000 (16:20 +0000)]
Improve accessibility of man.cgi(8) in various respects,
in particular adding <header>, <main>, and <nav> elements
and role and aria-label attributes in several places.
Patch from Anna Vyalkova <cyber at sysrq dot in>,
minimally tweaked by me.

2 years agoPut the HTML comment containing the Copyright header (if any)
Ingo Schwarze [Mon, 4 Jul 2022 14:37:33 +0000 (14:37 +0000)]
Put the HTML comment containing the Copyright header (if any)
between the <head> and the <body> rather than before the <head>
because the <meta charset="utf-8"/> element ought to be within
the first 1024 bytes of the HTML code.
Issue found with validator.w3.org.

2 years agospelling; patch from jsg@
Ingo Schwarze [Sun, 3 Jul 2022 14:36:00 +0000 (14:36 +0000)]
spelling; patch from jsg@

2 years agoInstead of the custom <div class="manual-text">, use the standard
Ingo Schwarze [Sun, 3 Jul 2022 14:29:44 +0000 (14:29 +0000)]
Instead of the custom <div class="manual-text">, use the standard
HTML <main> element.  The benefit is that it has the ARIA landmark
role "main" by default.  To ease the transition for people using
their own CSS file instead of mandoc.css, retain the custom class
for now.

I had this idea in a discussion with Anna Vyalkova <cyber at sysrq dot in>.
Patch from Anna, slightly tweaked by me.

2 years agoIn groff commit 78e66624 on May 7 20:15:33 2021 +1000,
Ingo Schwarze [Sun, 26 Jun 2022 20:33:43 +0000 (20:33 +0000)]
In groff commit 78e66624 on May 7 20:15:33 2021 +1000,
G. Branden Robinson changed the -T ascii rendering
of \(sd, the "second" symbol, U+2033 DOUBLE PRIME, from '' to ".
Follow suit in mandoc.

2 years agoadditional info regarding the .nf <br/> issue
Ingo Schwarze [Sun, 26 Jun 2022 20:21:22 +0000 (20:21 +0000)]
additional info regarding the .nf <br/> issue

2 years agoIf an .Xr macro contains a section argument, write an aria-label attribute
Ingo Schwarze [Sat, 25 Jun 2022 12:44:25 +0000 (12:44 +0000)]
If an .Xr macro contains a section argument, write an aria-label attribute
such that users of screen readers aren't forced to listen to lengthy and
distracting readings like "mdoc, left parenthesis, 7, right parenthesis".

Based on a patch from Anna Vyalkova <cyber at sysrq dot in>,
significantly tweaked by me.

2 years agoImprove accessibility of -T html -O toc output by using the <nav> element
Ingo Schwarze [Fri, 24 Jun 2022 11:15:53 +0000 (11:15 +0000)]
Improve accessibility of -T html -O toc output by using the <nav> element
in the DPUB-ARIA doc-toc role.
Patch from Anna Vyalkova <cyber at sysrq dot in> slightly tweaked by me.

This is hopefully the start of a collaboration to improve accessibility
of Unix manual pages using the WAI-ARIA, HTML-ARIA, and DPUB-ARIA standards.
Progress appears to be possible without changing *anything* with respect to
the way manual pages are written.  Instead, it seems sufficient to properly
translate semantic cues already implied by existing mdoc(7) markup into the
appropriate HTML elements and ARIA attributes.  Overall, the total length
of HTML output is likely to increase slightly, but not much.

2 years agoDelete the statement that the default stylesheet only used CSS1
Ingo Schwarze [Wed, 22 Jun 2022 17:37:59 +0000 (17:37 +0000)]
Delete the statement that the default stylesheet only used CSS1
because that has no longer been true for some time now.

I would certainly like to adhere to a coherent standard and state
which one that is.  Unfortunately, the W3C deliberately smashed
the CSS standard into pieces such that a coherent standard no
longer exists and such that statements about standard conformance
have become next to meaningless.  Consequently, i now remain
reluctantly silent regarding CSS standard(s) conformance.

Going back to CSS2.1, published in 2011, which was the last CSS
standard in the proper sense of the word, is not an option because
it has gaping holes in functionality and is no longer adequate for
use on today's WWW.

2 years ago#include <stddef.h>, needed for NULL; bug reported by op@
Ingo Schwarze [Tue, 21 Jun 2022 10:34:14 +0000 (10:34 +0000)]
#include <stddef.h>, needed for NULL; bug reported by op@

2 years agoWhen looking for the next block to tag, we aren't interested in children
Ingo Schwarze [Wed, 8 Jun 2022 16:31:46 +0000 (16:31 +0000)]
When looking for the next block to tag, we aren't interested in children
of the current block but really want the next block instead.  This fixes
a segfault reported by Evan Silberman <evan at jklol dot net> on bugs@.

2 years agoSurprisingly, every escape sequence can also be used as an argument
Ingo Schwarze [Wed, 8 Jun 2022 13:23:57 +0000 (13:23 +0000)]
Surprisingly, every escape sequence can also be used as an argument
delimiter for an outer escape sequence, in which case the delimiting
escape sequence retains its syntax but usually ignores its argument
and loses its inherent effect.  Add rudimentary support for this
syntax quirk in order to improve parsing compatibility with groff.

2 years agoSplit the excessively generic diagnostic message "invalid escape sequence"
Ingo Schwarze [Tue, 7 Jun 2022 09:54:40 +0000 (09:54 +0000)]
Split the excessively generic diagnostic message "invalid escape sequence"
into the more specific messages "invalid escape argument delimiter"
and "invalid escape sequence argument".

2 years agoPurge duplicate error reporting from the .tr request parser:
Ingo Schwarze [Tue, 7 Jun 2022 09:41:59 +0000 (09:41 +0000)]
Purge duplicate error reporting from the .tr request parser:
the error was already reported earlier when roff_expand()
called roff_escape().

2 years agoTo better match groff parsing, reject digits and some mathematical
Ingo Schwarze [Mon, 6 Jun 2022 19:23:13 +0000 (19:23 +0000)]
To better match groff parsing, reject digits and some mathematical
operators as argument delimiters for some escape sequences that take
numerical arguments, in the same way as it had already been done for \h.

Argument delimiter parsing for escape sequences taking numerical arguments
is not perfect yet.  In particular, when a character representing a
scaling unit is abused as the argument delimiter, parsing for that
character becomes context-dependent, and it is no longer possible to
find the end of the escape sequence without calling the full numerical
expression parser, which i refrain from attempting in this commit.

For now, continuing to misparse insane constructions like \Bc1c+1cc
(which is valid in groff and resolves to "1" because 1c+1c = two
centimeters is a valid numerical expression and 'c' is also a valid
delimiter) is a small price to pay for keeping complexity at bay
and for not losing focus in the ongoing series of refinements.

2 years agoadjust two desired error messages after roff_escape.c rev. 1.11
Ingo Schwarze [Mon, 6 Jun 2022 12:19:03 +0000 (12:19 +0000)]
adjust two desired error messages after roff_escape.c rev. 1.11
improved diagnostics for the \C escape sequence

2 years agoAllow arbitrary argument delimiters for \C, like groff does.
Ingo Schwarze [Mon, 6 Jun 2022 12:09:48 +0000 (12:09 +0000)]
Allow arbitrary argument delimiters for \C, like groff does.
The restriction of only allowing ' as the delimiter was introduced
by kristaps@ on 2011/04/09 when he first supported \C.
For most other escape sequences, similar restrictions were relaxed
later on, but for the rarely used \C, it was apparently forgotten.

While here, reject empty character names: they are never valid.

2 years agoadd and update a few entries
Ingo Schwarze [Mon, 6 Jun 2022 06:36:01 +0000 (06:36 +0000)]
add and update a few entries

2 years agoWith the improved escape sequence parser, it becomes easy to also improve
Ingo Schwarze [Sun, 5 Jun 2022 13:54:09 +0000 (13:54 +0000)]
With the improved escape sequence parser, it becomes easy to also improve
diagnostics.  Distinguish "incomplete escape sequence", "invalid special
character", and "unknown special character" from the generic "invalid
escape sequence", also promoting them from WARNING to ERROR because
incomplete escape sequences are severe syntax violations and because
encountering an invalid or unknown special character makes it likely
that part of the document content intended by the authors gets lost.

2 years agoSmall cleanup of error reporting:
Ingo Schwarze [Sun, 5 Jun 2022 10:19:54 +0000 (10:19 +0000)]
Small cleanup of error reporting:
call mandoc_msg() only once at the end, not sometimes in the middle,
classify incomplete, non-expanding escape sequences as ESCAPE_ERROR,
and also reduce the number of return statemants;
no formatting change intended.

2 years agoDuring identifier parsing, handle undefined escape sequences
Ingo Schwarze [Fri, 3 Jun 2022 12:15:55 +0000 (12:15 +0000)]
During identifier parsing, handle undefined escape sequences
in the same way as groff:
* \\ is always reduced to \
* \. is always reduced to .
* other undefined escape sequences are usually reduced to the escape name,
for example \G to G, except during the expansion of expanding escape
sequences having the standard argument form (in particular \* and \n),
in which case the backslash is preserved literally.

Yes, this is confusing indeed.
For example, the following have the same meaning:
* .ds \.   and   .ds .     which is not the same as   .ds \\.
* \*[\.]   and   \*[.]     which is not the same as   \*[\\.]
* .ds \G   and   .ds G     which is not the same as   .ds \\G
* \*[\G]   and   \*[\\G]   which is not the same as   \*[G]   <- sic!

To feel less dirty, have a leaning toothpick, if you are so inclined.

This patch also slightly improves the string shown by the "escaped
character not allowed in a name" error message.

2 years agoSince \. is not a character escape sequence, re-classify it from the
Ingo Schwarze [Thu, 2 Jun 2022 14:51:41 +0000 (14:51 +0000)]
Since \. is not a character escape sequence, re-classify it from the
wrong parsing class ESCAPE_SPECIAL to the better-suited parsing class
ESCAPE_UNDEF, exactly like it is already done for the similar \\,
which isn't a character escape sequence either.

No formatting change is intended just yet, but this will matter for
upcoming improvements in the parser for roff(7) macro, string, and
register names.

See the node "5.23.2 Copy Mode" in "info groff" regarding
what \\ and \. really mean.

2 years agoAvoid the layering violation of re-parsing for \E in roff_expand().
Ingo Schwarze [Thu, 2 Jun 2022 11:29:07 +0000 (11:29 +0000)]
Avoid the layering violation of re-parsing for \E in roff_expand().
To that end, add another argument to roff_escape()
returning the index of the escape name.
This also makes the code in roff_escape() a bit more uniform
in so far as it no longer needs the "char esc_name" local variable
but now does everything with indices into buf[].
No functional change.

2 years agoFix a buffer overrun in the roff(7) escape sequence parser that could
Ingo Schwarze [Wed, 1 Jun 2022 23:20:26 +0000 (23:20 +0000)]
Fix a buffer overrun in the roff(7) escape sequence parser that could
be triggered by macro arguments ending in double backslashes, for
example if people wrote .Sq "\\" instead of the correct .Sq "\e".

The bug was hard to find because it caused a segfault only very rarely,
according to my measurements with a probability of less than one permille.
I'm sorry that the first one to hit the bug was an arm64 release build
run by deraadt@.  Thanks to bluhm@ for providing access to an arm64
machine for debugging purposes.  In the end, the bug turned out to be
architecture-independent.

The reason for the bug was that i assumed an invariant that does not exist.
The function roff_parse_comment() is very careful to make sure that the
input buffer does not end in an escape character before passing it on,
so i assumed this is still true when reaching roff_expand() immediately
afterwards.  But roff_expand() can also be reached from roff_getarg(),
in which case there *can* be a lone escape character at the end of the
buffer in case copy mode processing found and converted a double
backslash.

Fix this by handling a trailing escape character correctly in the
function roff_escape().

The lesson here probably is to refrain from assuming an invariant
unless verifying that the invariant actually holds is reasonably
simple.  In some cases, in particular for invariants that are important
but not simple, it might also make sense to assert(3) rather than just
assume the invariant.  An assertion failure is so much better than a
buffer overrun...

2 years agoRudimentary implementation of the \A escape sequence, following groff
Ingo Schwarze [Tue, 31 May 2022 20:23:05 +0000 (20:23 +0000)]
Rudimentary implementation of the \A escape sequence, following groff
semantics (test identifier for syntactical validity), not at all
following the completely unrelated Heirloom semantics (define
hyperlink target position).

The main motivation for providing this implementation is to get \A
into the parsing class ESCAPE_EXPAND that corresponds to groff parsing
behaviour, which is quite similar to the \B escape sequence (test
numerical expression for syntactical validity).  This is likely
to improve parsing of nested escape sequences in the future.

Validation isn't perfect yet.  In particular, this implementation
rejects \A arguments containing some escape sequences that groff
allows to slip through.  But that is unlikely to cause trouble even
in documents using \A for non-trivial purposes.  Rejecting the nested
escapes in question might even improve robustnest because the rejected
names are unlikely to really be usable for practical purposes - no
matter that groff dubiously considers them syntactically valid.

2 years agoTrivial patch to put the roff(7) \g (interpolate format of register)
Ingo Schwarze [Tue, 31 May 2022 18:09:57 +0000 (18:09 +0000)]
Trivial patch to put the roff(7) \g (interpolate format of register)
escape sequence into the correct parsing class, ESCAPE_EXPAND.
Expansion of \g is supposed to work exactly like the expansion
of the related escape sequence \n (interpolate register value),
but since we ignore the .af (assign output format) request,
we just interpolate an empty string to replace the \g sequence.

Surprising as it may seem, this actually makes a formatting difference
for deviate input like ".O\gNx" which used to raise bogus "escaped
character not allowed in a name" and "skipping unknown macro" errors
and printed nothing, whereas now it correctly prints "OpenBSD".

2 years agoDummy implementation of the roff(7) \V (interpolate environment variable)
Ingo Schwarze [Mon, 30 May 2022 23:03:47 +0000 (23:03 +0000)]
Dummy implementation of the roff(7) \V (interpolate environment variable)
escape sequence.  This is needed to get \V into the correct parsing
class, ESCAPE_EXPAND.

It is intentional that mandoc(1) output is *not* influenced by environment
variables, so interpolate the name of the variable with some decorating
punctuation rather than interpolating its value.

2 years agoRe-classify the roff(7) \r (reverse line feed) escape sequence
Ingo Schwarze [Fri, 20 May 2022 13:09:13 +0000 (13:09 +0000)]
Re-classify the roff(7) \r (reverse line feed) escape sequence
from "ignore" to "unsupported" because when an input file uses it,
mandoc(1) is likely to significantly misformat the output,
usually showing parts of the output in a different order
than the author intended.

2 years agoTest the handling of some additional one-character escape sequences
Ingo Schwarze [Fri, 20 May 2022 12:32:29 +0000 (12:32 +0000)]
Test the handling of some additional one-character escape sequences
that take no argument and are ignored: \% \& \^ \a \d \t \u \{ \| \}
No change to parsing or formatting needed.

2 years agofollowing the fixed parsing direction of roff_expand() in roff.c rev. 1.388,
Ingo Schwarze [Thu, 19 May 2022 16:19:13 +0000 (16:19 +0000)]
following the fixed parsing direction of roff_expand() in roff.c rev. 1.388,
some diagnostics now appear in a more reasonable order, too

2 years agoAdjust a column number in an error message
Ingo Schwarze [Thu, 19 May 2022 16:09:26 +0000 (16:09 +0000)]
Adjust a column number in an error message
after the roff_expand() reorganization in roff.c rev. 1.388.

The new parsing direction has two effects:
1. Correct output when a line contains more than one expanding
escape sequence that has a side effect.
2. Column numbers in diagnostic messages now report the changed
column numbers after any expansions left of them have taken place;
in the past, column numbers refered to the original input line.

Arguably, item 2 was a bit better in its old state, but slightly
less helpful diagnostics are a small price to pay for correct
output.  Besides, when the expansion of user-defined strings or
macros is involved, in many cases, mandoc(1) is already unable to
report meaningful line and column numbers, so item 2 is not a
noteworthy regression.  The effort and code complication for fixing
that would probably be excessive, in particular since well-written
manual pages are not supposed to use such features in the first place.

2 years agofix a wrong column number that got fixed as a side effect
Ingo Schwarze [Thu, 19 May 2022 15:44:33 +0000 (15:44 +0000)]
fix a wrong column number that got fixed as a side effect
of the roff_expand() reorganization in roff.c rev. 1.388

2 years agoremove a bogus warning that went away as a side effect
Ingo Schwarze [Thu, 19 May 2022 15:38:00 +0000 (15:38 +0000)]
remove a bogus warning that went away as a side effect
of the roff_expand() reorganization in roff.c rev. 1.388

2 years agoMake roff_expand() parse left-to-right rather than right-to-left.
Ingo Schwarze [Thu, 19 May 2022 15:37:47 +0000 (15:37 +0000)]
Make roff_expand() parse left-to-right rather than right-to-left.
Some escape sequences have side effects on global state, implying
that the order of evaluation matters.  For example, this fixes the
long-standing bug that "\n+x\n+x\n+x" after ".nr x 0 1" used to
print "321"; now it correctly prints "123".

Right-to-left parsing was convenient because it implicitly handled
nested escape sequences.  With correct left-to-right parsing, nesting
now requires an explicit implementation, here solved as follows:
1. Handle nested expanding escape sequences iteratively.
When finding one, expand it, then retry parsing the enclosing escape
sequence from the beginning, which will ultimately succeed as soon
as it no longer contains any nested expanding escape sequences.
2. Handle nested non-expanding escape sequences recursively.
When finding one, the escape sequence parser calls itself to find
the end of the inner sequence, then continues parsing the outer
sequence after that point.

This requires the mandoc_escape() function to operate in two different
modes.  The roff(7) parser uses it in a mode where it generates
diagnostics and may return an expansion request instead of a parse
result.  All other callers, in particular the formatters, use it
in a simpler mode that never generates diagnostics and always returns
a definite parsing result, but that requires all expanding escape
sequences to already have been expanded earlier.  The bulk of the
code is the same for both modes.
Since this required a major rewrite of the function anyway, move
it into its own new file roff_escape.c and out of the file mandoc.c,
which was misnamed in the first place and lacks a clear focus.

As a side benefit, this also fixes a number of assertion failures
that tb@ found with afl(1), for example "\n\\\\*0", "\v\-\\*0",
and "\w\-\\\\\$0*0".

As another side benefit, it also resolves some code duplication
between mandoc_escape() and roff_expand() and centralizes all
handling of escape sequences (except for expansion) in roff_escape.c,
hopefully easing maintenance and feature improvements in the future.

While here, also move end-of-input handling out of the complicated
function roff_expand() and into the simpler function roff_parse_comment(),
making the logic easier to understand.

Since this is a major reorganization of a central component of
mandoc(1), stability of the program might slightly suffer for a few
weeks, but i believe that's not a problem at this point of the
release cycle.  The new code already satisfies the regression suite,
but more tweaking and regression testing to further improve the
handling of various escape sequences will likely follow in the near
future.

2 years agoimprove a comment explaining a particularly nasty hack; no code change
Ingo Schwarze [Thu, 19 May 2022 14:48:56 +0000 (14:48 +0000)]
improve a comment explaining a particularly nasty hack; no code change

2 years agoSplit a new function roff_parse_comment() out of roff_expand() because this
Ingo Schwarze [Sun, 1 May 2022 16:22:06 +0000 (16:22 +0000)]
Split a new function roff_parse_comment() out of roff_expand() because this
functionality is not needed when called from roff_getarg().  This makes the
long and complicated function roff_expand() significantly shorter, and also
simpler in so far as it no longer needs to return ROFF_APPEND.
No functional change intended.

2 years agoProvide a new function roff_req_or_macro() to parse and handle a request
Ingo Schwarze [Sat, 30 Apr 2022 18:51:36 +0000 (18:51 +0000)]
Provide a new function roff_req_or_macro() to parse and handle a request
or macro, including context-dependent error handling inside tbl(7) code
and inside .ce/.rj blocks.  Use it both in the top level roff(7) parser
and inside conditional blocks.

This fixes an assertion failure triggered by ".if 1 .ce" inside tbl(7)
code, found by tb@ using afl(1).

As a side benefit for readability, only one place remains in the
code that calls the main handler functions for the various roff(7)
requests.  This patch also improves column numbers in some error
messages and various comments.

2 years agoAdd comments to some of the enum roff_tok values;
Ingo Schwarze [Sat, 30 Apr 2022 15:09:26 +0000 (15:09 +0000)]
Add comments to some of the enum roff_tok values;
particularly useful for values that have non-obvious semantics
like ROFF_MAX, ROFF_cblock, ROFF_RENAMED, and TOKEN_NONE;
no code change.

2 years agoRefactor the handler function roff_block_sub() for clarity and simplicity.
Ingo Schwarze [Sat, 30 Apr 2022 11:32:42 +0000 (11:32 +0000)]
Refactor the handler function roff_block_sub() for clarity and simplicity.

1. Do not needlessly access the function pointer table roffs[].
Instead, simply call the block closing function directly.

2. Sort code: handle both cases of block closing at the beginning
of the function rather than one at the beginning and one at the end.

3. Trim excessive, partially repetitive and obvious comments, also
making the comments considerably more precise.

No functional change.

2 years agoThe syntax of the roff(7) .mc request is quite special
Ingo Schwarze [Thu, 28 Apr 2022 16:21:09 +0000 (16:21 +0000)]
The syntax of the roff(7) .mc request is quite special
and the roff_onearg() parsing function is too generic,
so provide a dedicated parsing function instead.

This fixes an assertion failure when an \o escape sequence is
passed as the argument; the bug was found by tb@ using afl(1).
It also makes mandoc output more similar to groff in various cases.

2 years agoElement next-line scopes may nest, so man_breakscope() may have to
Ingo Schwarze [Thu, 28 Apr 2022 10:26:37 +0000 (10:26 +0000)]
Element next-line scopes may nest, so man_breakscope() may have to
break multiple element next-line scopes at the same time, similar to
what man_descope() already does for unconditional rewinding.

This fixes an assertion failure that tb@ found with afl(1), caused
by .SH .I .I .BI and similar sequences of macros without arguments.

2 years agoThe .AT, .DT, and .UC macros are allowed inside next-line scope
Ingo Schwarze [Wed, 27 Apr 2022 17:11:24 +0000 (17:11 +0000)]
The .AT, .DT, and .UC macros are allowed inside next-line scope
and never produce output at the place of their invocation.

Minibugs found while investigating unrelated afl(1) reports from tb@.

2 years agoFix three bugs regarding the interaction of \z and \h:
Ingo Schwarze [Wed, 27 Apr 2022 13:41:13 +0000 (13:41 +0000)]
Fix three bugs regarding the interaction of \z and \h:

1. The combination \z\h is a no-op whatever the argument may be.
In the past, the \z only affected the first space character generated
by the \h, which was wrong.

2. For the conbination \zX\h with a positive argument, the first
space resulting from the \h is not printed but consumed by the \z.

3. For the combination \zX\h with a negative argument, application
of the \z needs to be completed before the \h can be started.
In the past, if this combination occurred at the beginning of an
output line, the \h backed up to the beginning of the line and
after that, the \z attempted to back up even further, triggering
an assertion.

Bugs found during an audit of assignments to termp->col that i
started after the bugfix tbl_term.c rev. 1.65.  The assertion
triggered by bug 3 was *not* yet found by afl(1).

2 years agotypo in example text: unsused -> unused; noticed by tb@
Ingo Schwarze [Tue, 26 Apr 2022 15:06:51 +0000 (15:06 +0000)]
typo in example text: unsused -> unused; noticed by tb@

2 years agoAt the end of every tbl(7) cell, clear the \z state.
Ingo Schwarze [Tue, 26 Apr 2022 14:52:05 +0000 (14:52 +0000)]
At the end of every tbl(7) cell, clear the \z state.
This is needed because the TERMP_MULTICOL mode is designed such
that term_tbl() buffers all the cells of the table row before the
normal reset logic near the end of term_flushln() can be reached.

This fixes an assertion failure triggered by \z near the end
of a table cell, found by tb@ using afl(1).

2 years agoIf a node is tagged explicitly, skip implicit tagging for that node.
Ingo Schwarze [Tue, 26 Apr 2022 11:38:38 +0000 (11:38 +0000)]
If a node is tagged explicitly, skip implicit tagging for that node.
Apart from making sense in the first place, this fixes an assertion
failure that happened when the calculated implicit tag did not match
the string value of the first child of the node,

Bug found by tb@ using afl(1).

2 years agoWhen we open a new .while loop, let's not attempt to close out
Ingo Schwarze [Sun, 24 Apr 2022 17:40:22 +0000 (17:40 +0000)]
When we open a new .while loop, let's not attempt to close out
another enclosing .while loop at the same time.
Instead, postpone the closing until the next iteration of ROFF_RERUN.

This prevents one-line constructions like ".while 0 .while 0 something"
and ".while rx .while rx .rr x" (which admittedly aren't particularly
useful) from dying of abort(3), which was a bug tb@ found with afl(1).

2 years agoIf a .shift request has a negative argument, do not use a negative array
Ingo Schwarze [Sun, 24 Apr 2022 13:38:46 +0000 (13:38 +0000)]
If a .shift request has a negative argument, do not use a negative array
index but use 0 instead of the argument, just like groff.
Warn about the invalid argument.
While here, fix the column number in another warning message.

Segfault reported by tb@, found with afl(1).

2 years agoIf the last data row of a tbl(7) contains nothing but a horizontal line,
Ingo Schwarze [Sat, 23 Apr 2022 14:02:17 +0000 (14:02 +0000)]
If the last data row of a tbl(7) contains nothing but a horizontal line,
do not skip closing the table and cleaning up memory at the end of the
table in the HTML output module.

This bug resulted in skipping the tblcalc() function and reusing
the existing roffcol array for the next tbl(7) processed.  If the
next table had more columns than the one ending with a horizontal
line in the last data row, uninitialized memory was read, potentially
resulting in near-infinite output.

The bug was introduced in rev. 1.29 (2018/11/26) but only fully exposed
by rev. 1.38 (2021/09/09).  Until rev. 1.37, it could only cause
misformatting and invalid HTML output syntax but not huge output
because up to that point, the function did not use the roffcol array.

Nasty bug found the hard way by Michael Stapelberg on the production
server manpages.debian.org.  Michael also supplied example files
and excellent instructions how to reproduce the bug, which was very
difficult because no real-world manual page is known that triggers
the bug by itself, so to reproduce the bug, mandoc(1) had to be
invoked with at least two file name arguments.

2 years agosupport for hunting memory leaks;
Ingo Schwarze [Thu, 14 Apr 2022 16:43:43 +0000 (16:43 +0000)]
support for hunting memory leaks;
designed and written last autumn, polished today

2 years agosome HTML/CSS issues from John Gardner
Ingo Schwarze [Thu, 14 Apr 2022 10:14:53 +0000 (10:14 +0000)]
some HTML/CSS issues from John Gardner

2 years agoprefer https links in man pages
Ingo Schwarze [Thu, 14 Apr 2022 10:10:22 +0000 (10:10 +0000)]
prefer https links in man pages
patch from jsg@
ok gnezdo@ miod@ jmc@

2 years agoTo prevent infinite recursion while expanding eqn(7) definitions,
Ingo Schwarze [Wed, 13 Apr 2022 20:26:19 +0000 (20:26 +0000)]
To prevent infinite recursion while expanding eqn(7) definitions,
we must not reset the recursion counter when moving beyond the end
of the *previous* expansion, but we may only do so when moving
beyond the rightmost position reached by *any* expansion in the
current equation.  This matters because definitions can nest;
consider:

.EQ
define inner "content"
define outer "inner outer"
outer
.EN

This endless loop was found by tb@ using afl(1).

Incidentally, GNU eqn(1) also performs an infinite loop in this
situation and then crashes when memory runs out, but that's not an
excuse for nasty behaviour of mandoc(1).

While here, consistently print the expanded content even when the
expansion is finally truncated.  While that is not likely to help
end-users, it may help authors of eqn(7) code to understand what's
going on.  Besides, it sends a very clear signal that something is
amiss, which was easy to miss in the past unless people
enabled -W error or used -T lint.

2 years agoDo not die on an assertion if an input file contains no section
Ingo Schwarze [Wed, 13 Apr 2022 14:45:50 +0000 (14:45 +0000)]
Do not die on an assertion if an input file contains no section
whatsoever and ends with a broken next-line scope.  Obviously, this
cannot happen in a real manual page, but mandoc(1) should not die
even when fed absurd input.

This bug was independently reported by both jsg@ and tb@ who both
found it with afl(1).

2 years agoSurprisingly, groff supports multiple copy mode escapes at the
Ingo Schwarze [Wed, 13 Apr 2022 13:19:34 +0000 (13:19 +0000)]
Surprisingly, groff supports multiple copy mode escapes at the
beginning of an escape sequence: \, \E, \EE, \EEE, and so on all do
the same outside copy mode, so let them do the same in mandoc(1), too.

This fixes an assertion failure triggered by \EE*X that tb@ found
with afl(1).  The first E was consumed by roff_expand(), but that
function failed to recognize the escape sequence as the expansion
of a user-defined string and handed it over to mandoc_escape(),
which consumed the second E and then died on an assertion because
it is not prepared to handle user-defined strings.  Fix this by
letting *both* functions handle arbitrary numbers of 'E's correctly.

2 years agoWhen calculating the with of spanned columns, which for example matters
Ingo Schwarze [Fri, 8 Apr 2022 16:53:45 +0000 (16:53 +0000)]
When calculating the with of spanned columns, which for example matters
for centering text spanning multiple tbl(7) columns, correctly account
for the spacing between columns instead of wrongly assuming the default
spacing of 3n.

Patch from Simon Branch <simonmbranch at gmail dot com>.

2 years agonew TODO entry: handle Unicode letters in tags
Ingo Schwarze [Sun, 27 Mar 2022 11:08:24 +0000 (11:08 +0000)]
new TODO entry: handle Unicode letters in tags

2 years agoThe demandoc(1) program neither reads nor writes any databases, so
Ingo Schwarze [Sun, 20 Mar 2022 15:41:47 +0000 (15:41 +0000)]
The demandoc(1) program neither reads nor writes any databases, so
delete a sentence taking about databases.  Having that sentence in
the first place probably was a copy-and-paste mistake when adopting
some text from the makewhatis(8) manual page.

Triggered by a smaller patch sent to discuss@
by Paul A. Patience <paul at apatience dot com>.

2 years agoAvoid legacy CSS2 syntax for the "display" property and use the CSS3
Ingo Schwarze [Thu, 17 Mar 2022 18:45:49 +0000 (18:45 +0000)]
Avoid legacy CSS2 syntax for the "display" property and use the CSS3
two-value syntax "display: inline flow;" instead.  In particular, there
is no need to establish a new block formatting context with "flow-root",
and in fact that's detrimental because it appears to introduce spurious
soft-wrap opportunities.

jmc@ reported a bogus line break between the opening angle bracket
generated by .Aq Mt and the following email address.

2 years agoJust say that the databases are intended for use by apropos(1), whatis(1),
Ingo Schwarze [Wed, 16 Mar 2022 23:26:14 +0000 (23:26 +0000)]
Just say that the databases are intended for use by apropos(1), whatis(1),
and man(1), without restricting that statement to "man -k".
Suggested by and patch OK'ed by jmc@.

While only apropos(1) and whatis(1) strictly require the database
and while our man(1) implementation can find many manual pages even
when no database is available or when the database is incomplete or
corrupt, it does use the database even without -k whenever possible.
Consequently, this change makes the manual page less confusing.

2 years agoIn the first example, use "mandoc -a" directly rather "mandoc -l".
Ingo Schwarze [Tue, 8 Feb 2022 18:30:22 +0000 (18:30 +0000)]
In the first example, use "mandoc -a" directly rather "mandoc -l".

It feels more natural to me to use -a directly when asking mandoc(1)
to use a pager.  The reason that "mandoc -l" does exactly the same
as "mandoc -a" is that "mandoc" is essentially "man -lc", so the -a
implied by -l negates the -c and the -l has no effect because it is
already the default for mandoc(1).

The more usual command for doing the same is "man -l foo.1 bar.1 ..."
but that's off-topic for the mandoc(1) manual page.

Patch on tech@ from Anders Damsgaard <anders at adamsgaard dot dk>.

2 years agoremove "please" from manual page;
Ingo Schwarze [Tue, 8 Feb 2022 18:27:45 +0000 (18:27 +0000)]
remove "please" from manual page;
patch from jsg@, ok jmc@ sthen@ millert@

3 years agoTedu support for the -xsh4.2 argument to the mdoc(7) .St macro origin origin/main origin/origin
Ingo Schwarze [Thu, 13 Jan 2022 08:42:15 +0000 (08:42 +0000)]
Tedu support for the -xsh4.2 argument to the mdoc(7) .St macro
because all of the following hold:
* It is an alias for a part of an ancient standard that is no longer important.
* To refer to that old standard, -xpg4.2 is readily available and portable.
* It is unused in OpenBSD, FreeBSD, and NetBSD.
* Groff never supported it.

I agreed with G. Branden Robinson that deleting this from mandoc
is preferable to adding it to groff.

3 years agoOnly sort the result array if it contains more than one element,
Ingo Schwarze [Thu, 13 Jan 2022 04:06:16 +0000 (04:06 +0000)]
Only sort the result array if it contains more than one element,
making the mansearch() function easier to read for human auditors.
No functional change on OpenBSD.

As observed by Mark Millard <marklmi at yahoo dot com>, neither the
latest version of POSIX 2008 nor C11 defines what qsort(3) should do
for base == NULL && nmemb == 0.
My impression is it is indeed undefined behaviour because the
standards say that base shall point to an array, NULL does not point
to an array, and while there is special wording saying that compar()
shall not be called if nmemb == 0, i fail to see any similar wording
stating that base shall not be accessed if nmemb == 0.
Consequently, this patch is also likely to improve standard conformance
and portability.

Minor issue found by Stefan Esser <se at FreeBSD> with UBSAN.
He sent a patch to bugs@, but my patch differs in a minor way.

3 years agoMore accurately represent cells containing horizontal lines in -T tree
Ingo Schwarze [Wed, 12 Jan 2022 04:54:05 +0000 (04:54 +0000)]
More accurately represent cells containing horizontal lines in -T tree
output.  In particular, do not represent "_" as "-", and distinguish "_"
from "\_" and "=" from "\=".
Output tweak following a related question from
Ted Bullock <tbullock at comlore dot com>.

3 years agoAccording to the tbl(7) manual, if a data cell contains only the
Ingo Schwarze [Wed, 12 Jan 2022 04:43:26 +0000 (04:43 +0000)]
According to the tbl(7) manual, if a data cell contains only the
two character sequence "\_" or "\=", a single or double horizontal
line is supposed to be drawn inside the cell, not joining its
neighbours.

I am not aware of any way to do that with HTML and/or CSS.
Still, it seems closer to the intent of the document author to draw
a horizontal line with <hr/>, even though that line will join the
neighbour cells, rather than printing a literal '_' or '=' character.

Formatting tweak inspired by a related question from
Ted Bullock <tbullock at comlore dot com>.

3 years agoIn one of the examples, the tbl(7) source code displayed
Ingo Schwarze [Wed, 12 Jan 2022 04:14:25 +0000 (04:14 +0000)]
In one of the examples, the tbl(7) source code displayed
contains a backslash that needs to be escaped, and the
missing escaping resulted in very misleading formatting.

Documentation bug found due to a question from
Ted Bullock <tbullock at comlore dot com>.

3 years agocolumn width specifications in tbl(7) HTML output
Ingo Schwarze [Wed, 12 Jan 2022 00:16:46 +0000 (00:16 +0000)]
column width specifications in tbl(7) HTML output

3 years agoWhen rendering the \h (horizontal motion) low-level roff(7) escape
Ingo Schwarze [Mon, 10 Jan 2022 18:01:35 +0000 (18:01 +0000)]
When rendering the \h (horizontal motion) low-level roff(7) escape
sequence in -T ps and -T pdf output mode, use an appropriate
horizontal distance by correctly using the term_len() utility
function.  Output from the -T ascii, -T utf8, and -T html modes
was already correct and remains unchanged.

Lennart Jablonka <hummsmith42 at gmail dot com> found and reported
this unit conversion bug (misinterpreting AFM units as if they were
en units) when rendering scdoc-generated manuals (which is a low
quality generator, but that's no excuse for mandoc misformatting \h)
on Alpine Linux.  Lennart also tested this patch.

3 years agomerge OpenBSD commit by jmc@:
Ingo Schwarze [Mon, 6 Dec 2021 16:26:08 +0000 (16:26 +0000)]
merge OpenBSD commit by jmc@:
sytle -> style; adapted from changes by SAITOH masanobu (NetBSD)

3 years agoMake sure that the configuration file is always read, even when
Ingo Schwarze [Fri, 5 Nov 2021 18:03:08 +0000 (18:03 +0000)]
Make sure that the configuration file is always read, even when
running with the -M option or with a MANPATH environment variable
that has neither a leading or trailing ":" nor any "::".  If -M or
MANPATH override the configuration file rather than adding to it,
just ignore any "manpath" directives while processing the configuration
file.

This fixes a bug reported by Jan Stary <hans at stare dot cz>
on misc@.

3 years agoCommit and commit message by deraadt@:
Ingo Schwarze [Fri, 5 Nov 2021 17:04:10 +0000 (17:04 +0000)]
Commit and commit message by deraadt@:
For open/openat, if the flags parameter does not contain O_CREAT, the
3rd (variadic) mode_t parameter is irrelevant.  Many developers in the past
have passed mode_t (0, 044, 0644, or such), which might lead future people
to copy this broken idiom, and perhaps even believe this parameter has some
meaning or implication or application. Delete them all.
This comes out of a conversation where tb@ noticed that a strange (but
intentional) pledge behaviour is to always knock-out high-bits from
mode_t on a number of system calls as a safety factor, and his bewilderment
that this appeared to be happening against valid modes (at least visually),
but no sorry, they are all irrelevant junk.  They could all be 0xdeafbeef.
ok millert

3 years agosimplify a few accesses to fields of structs, using auxiliary pointer
Ingo Schwarze [Sun, 17 Oct 2021 21:05:54 +0000 (21:05 +0000)]
simplify a few accesses to fields of structs, using auxiliary pointer
variables that are already present (and used nearby) in the code;
no functional change

3 years agoSimplify the code building lists of spans, no output change intended.
Ingo Schwarze [Sun, 17 Oct 2021 20:48:28 +0000 (20:48 +0000)]
Simplify the code building lists of spans, no output change intended.

A comment in the code claimed that the list of spans would be sorted,
but the sorting did not actually work.  The layout "LSSS,LLSL" resulted
in the list "0-3, 1-2", whereas the layout "LLSL,LSSS" resulted
in the list "1-2, 0-3".  Since sorting serves no purpose, just leave
the list unsorted.

3 years agobetter error message if mandocd is not found
Ingo Schwarze [Fri, 15 Oct 2021 15:04:02 +0000 (15:04 +0000)]
better error message if mandocd is not found

3 years agoClean up memory handling in spawn_pager(), free(3)ing everything
Ingo Schwarze [Mon, 4 Oct 2021 21:29:17 +0000 (21:29 +0000)]
Clean up memory handling in spawn_pager(), free(3)ing everything
that is malloc(3)ed.  In addition to being less confusing, the new
code is also shorter by two lines.

3 years agoIn man(1) mode, properly clean up the resn[] result array
Ingo Schwarze [Mon, 4 Oct 2021 20:24:06 +0000 (20:24 +0000)]
In man(1) mode, properly clean up the resn[] result array
after processing each name given on the command line.

Failure to do so resulted in a memory leak of about 50 kilobytes
per name given on the command line.  Since man(1) uses a few
Megabytes of memory anyway and people rarely give hundreds of names
on the command line, this leak did not cause practical problems,
but cleaning up properly is better in any case.

3 years agoProvide a cleanup function for the term_tab module, freeing memory
Ingo Schwarze [Mon, 4 Oct 2021 18:56:31 +0000 (18:56 +0000)]
Provide a cleanup function for the term_tab module, freeing memory
and resetting the internal state to the initial state.
Call this function from the proper place in term_free().

With the way the module is currently used, this does not imply any
functional change, but doing proper cleanup is more robust, makes
it easier during code review to understand what is going on, and
makes it explicit that there is no memory leak.

3 years agostore the operating system name obtained from uname(3) in the adequate
Ingo Schwarze [Mon, 4 Oct 2021 14:19:14 +0000 (14:19 +0000)]
store the operating system name obtained from uname(3) in the adequate
struct together with similar state date rather than in a function-scope
static variable, such that it can be free(3)d in roff_man_free();
no functional change

3 years agoDo not leak 64 bytes of heap memory every time a manual page calls
Ingo Schwarze [Mon, 4 Oct 2021 10:12:27 +0000 (10:12 +0000)]
Do not leak 64 bytes of heap memory every time a manual page calls
a user-defined macro.  Calls of standard mdoc(7) and man(7) macros
were unaffected, so the effect on OpenBSD manual pages was small,
about 80 Kilobytes grand total for a full run of "makewhatis
/usr/share/man".

Argument expansion contexts for user-defined macros are stored on
a stack that grows as needed if calls of user-defined macros are
nested or recursive.  Individual stack entries contain dynamically
allocated arrays of pointers to arguments; these argument arrays
also grow as needed if user-defined macros take more than eight
arguments.  The mistake was that argument arrays of already
initialized expansion contexts were leaked rather than reused on
subsequent macro calls.

I found this issue in a systematic hunt for memory leaks after
Michael <Stapelberg at Debian> reported memory exhaustion problems
on the production server manpages.debian.org.  This sub-Megabyte
leak is not the cause of Michael's trouble, though, where Gigabytes
of memory are being wasted.  We are still investigating whether the
original problem may be related to his supervisor process, which is
written in Go, rather than to mandoc.

3 years agotagging issues from weerd@ regarding hyphens
Ingo Schwarze [Fri, 1 Oct 2021 08:58:37 +0000 (08:58 +0000)]
tagging issues from weerd@ regarding hyphens

3 years agoRevert part of the previous diff to fix a regression (another endless loop)
Ingo Schwarze [Tue, 28 Sep 2021 17:06:59 +0000 (17:06 +0000)]
Revert part of the previous diff to fix a regression (another endless loop)
reported by Michael <Stapelberg at Debian> in the Linux md(4) manual.

The reason the colwidth[] array is needed is not that it stores widths
different from those in tbl->cols[].width, but that only part of the
columns participate in the comparisons, i.e. only those intersecting
at least one span the still requires width distribution.

3 years agotwo typos; patch from Raf Czlonka <rczlonka at gmail dot com>
Ingo Schwarze [Tue, 28 Sep 2021 15:41:41 +0000 (15:41 +0000)]
two typos; patch from Raf Czlonka <rczlonka at gmail dot com>

3 years agoSevan Janiyan resigned from the NetBSD project and pkgsrc in 2020.
Ingo Schwarze [Sat, 25 Sep 2021 15:42:08 +0000 (15:42 +0000)]
Sevan Janiyan resigned from the NetBSD project and pkgsrc in 2020.
He is now busy with the early stages of development of Viewpoint Linux.

3 years agorelease 1.14.6 VERSION_1_14_6
Ingo Schwarze [Thu, 23 Sep 2021 18:03:00 +0000 (18:03 +0000)]
release 1.14.6

3 years agocredits for release testing
Ingo Schwarze [Thu, 23 Sep 2021 17:12:00 +0000 (17:12 +0000)]
credits for release testing

3 years agohandle man3c/fopen.3c in main.c/fs_*()
Ingo Schwarze [Tue, 21 Sep 2021 17:58:13 +0000 (17:58 +0000)]
handle man3c/fopen.3c in main.c/fs_*()

3 years agoPOSIX make(1) does not support prerequisites on suffix rules.
Ingo Schwarze [Tue, 21 Sep 2021 11:04:40 +0000 (11:04 +0000)]
POSIX make(1) does not support prerequisites on suffix rules.
For HTML generation, the "mandoc" prerequisite isn't needed anyway
because ${WWW_MANS} already explicitly depends on mandoc.
Issue reported by Sevan Janiyan and Leah Neukirchen.

This is not critical for release because it is only used for
a maintainer target.  While here, i also fixed the associated
shell command to use the freshly built mandoc binary rather
than whatever may be in the $PATH.

3 years agomore details about Mac OS X; information from Sevan Janiyan
Ingo Schwarze [Mon, 20 Sep 2021 13:25:42 +0000 (13:25 +0000)]
more details about Mac OS X; information from Sevan Janiyan

3 years agomake the path to ar(1) configurable, needed by NixOS;
Ingo Schwarze [Mon, 20 Sep 2021 10:19:51 +0000 (10:19 +0000)]
make the path to ar(1) configurable, needed by NixOS;
suggested by Lukas Epple <sternenseemann at systemli dot org>

3 years agoCreate the link from ./man to ./mandoc in the "all" target rather than
Ingo Schwarze [Mon, 20 Sep 2021 10:14:34 +0000 (10:14 +0000)]
Create the link from ./man to ./mandoc in the "all" target rather than
in the "regress" target.  That makes manual "cd regress && ./regress.pl"
a bit less fragile.
The idea came up in a conversation with Thomas Klausner <wiz at NetBSD>.

3 years agoisspace(3) requires an unsigned argument;
Ingo Schwarze [Sun, 19 Sep 2021 18:14:24 +0000 (18:14 +0000)]
isspace(3) requires an unsigned argument;
bug reported by Thomas Klausner <wiz at NetBSD>

3 years agoclarify the meaning of a complicated mixed signed/unsigned expression;
Ingo Schwarze [Sun, 19 Sep 2021 18:07:09 +0000 (18:07 +0000)]
clarify the meaning of a complicated mixed signed/unsigned expression;
Thomas Klausner <wiz at NetBSD> reported a compiler warning

3 years agodo not ship with an old OpenBSD version number
Ingo Schwarze [Sun, 19 Sep 2021 16:19:09 +0000 (16:19 +0000)]
do not ship with an old OpenBSD version number

3 years agosome more portability improvements
Ingo Schwarze [Sun, 19 Sep 2021 15:21:13 +0000 (15:21 +0000)]
some more portability improvements