At 2023-08-18T03:24:53+0200, Ingo Schwarze wrote:
> > Understanding *roff a little better 6 years later, I can more easily
> > imagine ways to run AT&T troff out of memory on a PDP-11.
> > Ultra-long diversions would be one way,[1]
> > [1] Nobody _except_ mandoc(1) seems to handle this well.  Credit
> >     where it's due.  https://savannah.gnu.org/bugs/?64229
> 
> Praise is usually nice to have, but i must admit this particular
> praise surprises me on more than one level.  :-)

And your reply did so for me!

> https://man.openbsd.org/roff.7#di says:
> 
>   di divname
>     Begin a diversion. Currently unsupported.   [by mandoc(1)]

Hah!  You'll soon see why I didn't anticipate that.

> I'm not completely convinced not supporting a particular request
> at all amounts to "handling it well".
> 
> Besides,
> 
>    $ time { printf '.di foo\n.nf\n'; yes abcdefghijklm; } | mandoc
>   mandoc: Cannot allocate memory
>     0m07.61s real     0m05.67s user     0m01.81s system
> 
> i.e. infinite input crashes mandoc - admittedly via err(3) after
> malloc(3) returns NULL, which is relatively controlled, but
> still a crash.

No kidding!  But check this out.

$ dpkg -l mandoc|tail -n 1
ii  mandoc         1.14.6-1     amd64        BSD manpage compiler toolset
$ { printf '.di foo\n.nf\n'; yes abcdefghijklm; } | mandoc; echo $?
0
$ time { printf '.di foo\n.nf\n'; yes abcdefghijklm; } | mandoc

real    0m1.161s
user    0m0.022s
sys     0m2.217s

I'm afraid I got a misleading impression of mandoc(1)'s performance
here.  ;-)

But something is clearly hinky in the mandoc build for Debian.

> But GNU troff isn't actually *that* much worse:
> 
>    $ time { printf '.di foo\n.nf\n'; yes abcdefghijklm; } | troff
>   Abort trap (core dumped) 
>     0m24.72s real     0m04.43s user     0m03.82s system

And it's doing actual work, by contrast.  ;-)

> Exiting via abort(3) is also a relatively contolled way of dying.

Yeah, I'd prefer that's what happened on GNU/Linux.

> This downside merely follows from the choice of the implementation
> language C++, which suffers from ill-designed, very messy error
> handling in general.

Well in this case, maybe the libstdc++ vendor.

> I'm not sure why you see a SIGKILL getting thrown at the troff process
> on your machine - but i *suspect* that may have nothing to do with GNU
> troff either and may be an implementation detail of whatever operating
> system, C++ compiler, and C++ standard library you are using.

My thoughts as well.

> Sure, on first sight, an explicit abort(3) being called on the C
> library level *might* look slightly safer than SIGKILL flying around -
> then again, i'm not really sure it makes a difference.  Whether that
> actually is a security risks depends on many details you did not
> disclose.  Quite possible it isn't.

I think the problem is simple.  Nothing checks for the integer
wraparound in the `int` that stores the vertical drawing position in
basic units.  On a "page" in GNU troff, you'll hit the implicit page
trap before that can happen,[1] but in a diversion, the vertical drawing
position can wrap from INT_MAX to INT_MIN without anyone noticing.

In a language with real data types, like Ada, Clark would have
foreclosed this failure mode in 1990 or so.

But I haven't yet proven my suspicions, so we'll see.  I doubt that
future opportunities to compare Ada favorably to C++ will dry up.

> > I'll say it before Ingo does: mandoc(1) (as I understand it) _does_
> > build a syntax tree for the entire document before producing output,
> > which enables some of the nice features that it has.
> 
> Correct.
> 
> However, before Alejandro gets carried away with enthusiasm, let
> me emphasize that is does the opposite of what Alejandro is asking
> for: He wants all the man(7) macros converted to roff(7) requests.
> Instead, mandoc *removes* all roff requests from the document such
> that it gets a pure man(7) syntax tree with (almost) no roff left in
> it - still making sure most of those roff requests take effect before
> being removed.

Ahhhh.  I think you reimplemented "environments" in the *roff sense. ;-)

> Sound impossible, almost paradoxical?  Yes it does,
> but it works surprisingly well all the same.  See this 12-year-old
> presentation,
> 
>   https://www.openbsd.org/papers/bsdcan11-mandoc-openbsd.html
> 
>   in particular page 12 "No way around some low-level roff requests."
>   and page 13 "Desperation lead to success: Paradigmatic switch"

I see.  You turned troff upside down, making formatter requests into
"macros" for man(7) and mdoc(7) (plus, quasi-environmental stuff).
Diabolical.  3:-)

Regards,
Branden

Attachment: signature.asc
Description: PGP signature

Reply via email to