[BACK]Return to eqn_parse.h CVS log [TXT][DIR] Up to [cvsweb.bsd.lv] / mandoc

File: [cvsweb.bsd.lv] / mandoc / eqn_parse.h (download)

Revision 1.4, Wed Apr 13 20:26:19 2022 UTC (23 months, 2 weeks ago) by schwarze
Branch: MAIN
CVS Tags: HEAD
Changes since 1.3: +4 -2 lines

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.

/* $Id: eqn_parse.h,v 1.4 2022/04/13 20:26:19 schwarze Exp $ */
/*
 * Copyright (c) 2014, 2017, 2018, 2022 Ingo Schwarze <schwarze@openbsd.org>
 * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 * External interface of the eqn(7) parser.
 * For use in the roff(7) and eqn(7) parsers only.
 */

struct roff_node;
struct eqn_box;
struct eqn_def;

struct	eqn_node {
	struct roff_node *node;    /* Syntax tree of this equation. */
	struct eqn_def	 *defs;    /* Array of definitions. */
	char		 *data;    /* Source code of this equation. */
	char		 *start;   /* First byte of the current token. */
	char		 *end;	   /* First byte of the next token. */
	size_t		  defsz;   /* Number of definitions. */
	size_t		  sz;      /* Length of the source code. */
	size_t		  toksz;   /* Length of the current token. */
	int		  sublen;  /* End of rightmost substitution, so far. */
	int		  subcnt;  /* Number of recursive substitutions. */
	int		  gsize;   /* Default point size. */
	int		  delim;   /* In-line delimiters enabled. */
	char		  odelim;  /* In-line opening delimiter. */
	char		  cdelim;  /* In-line closing delimiter. */
};


struct eqn_node	*eqn_alloc(void);
struct eqn_box	*eqn_box_new(void);
void		 eqn_box_free(struct eqn_box *);
void		 eqn_free(struct eqn_node *);
void		 eqn_parse(struct eqn_node *);
void		 eqn_read(struct eqn_node *, const char *);
void		 eqn_reset(struct eqn_node *);