From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from localhost (fantadrom.bsd.lv [local]); by fantadrom.bsd.lv (OpenSMTPD) with ESMTPA id 2be961c0; for ; Wed, 14 Jan 2015 23:27:11 -0500 (EST) Date: Wed, 14 Jan 2015 23:27:11 -0500 (EST) Message-Id: <8250470002905201232.enqueue@fantadrom.bsd.lv> X-Mailinglist: mdocml-source Reply-To: source@mdocml.bsd.lv MIME-Version: 1.0 From: schwarze@mdocml.bsd.lv To: source@mdocml.bsd.lv Subject: mdocml: Fatal errors no longer exist. X-Mailer: activitymail 1.26, http://search.cpan.org/dist/activitymail/ Content-Type: text/plain; charset=utf-8 Log Message: ----------- Fatal errors no longer exist. If a file can be opened, mandoc will produce some output; at worst, the output may be almost empty. Simplifies error handling and frees a message type for future use. Modified Files: -------------- mdocml: cgi.c demandoc.c libmandoc.h main.c man.1 man.c mandoc.1 mandoc.3 mandoc.h mandocdb.c mdoc.c read.c Revision Data ------------- Index: libmandoc.h =================================================================== RCS file: /home/cvs/mdocml/mdocml/libmandoc.h,v retrieving revision 1.54 retrieving revision 1.55 diff -Llibmandoc.h -Llibmandoc.h -u -p -r1.54 -r1.55 --- libmandoc.h +++ libmandoc.h @@ -60,7 +60,7 @@ struct mdoc *mdoc_alloc(struct roff *, s const char *, int); void mdoc_reset(struct mdoc *); int mdoc_parseln(struct mdoc *, int, char *, int); -int mdoc_endparse(struct mdoc *); +void mdoc_endparse(struct mdoc *); void mdoc_addspan(struct mdoc *, const struct tbl_span *); void mdoc_addeqn(struct mdoc *, const struct eqn *); @@ -69,7 +69,7 @@ struct man *man_alloc(struct roff *, str const char *, int); void man_reset(struct man *); int man_parseln(struct man *, int, char *, int); -int man_endparse(struct man *); +void man_endparse(struct man *); void man_addspan(struct man *, const struct tbl_span *); void man_addeqn(struct man *, const struct eqn *); Index: demandoc.c =================================================================== RCS file: /home/cvs/mdocml/mdocml/demandoc.c,v retrieving revision 1.12 retrieving revision 1.13 diff -Ldemandoc.c -Ldemandoc.c -u -p -r1.12 -r1.13 --- demandoc.c +++ demandoc.c @@ -44,7 +44,7 @@ main(int argc, char *argv[]) { struct mparse *mp; struct mchars *mchars; - int ch, i, list; + int ch, fd, i, list; extern int optind; progname = strrchr(argv[0], '/'); @@ -78,7 +78,7 @@ main(int argc, char *argv[]) argv += optind; mchars = mchars_alloc(); - mp = mparse_alloc(MPARSE_SO, MANDOCLEVEL_FATAL, NULL, mchars, NULL); + mp = mparse_alloc(MPARSE_SO, MANDOCLEVEL_BADARG, NULL, mchars, NULL); assert(mp); if (0 == argc) @@ -86,7 +86,11 @@ main(int argc, char *argv[]) for (i = 0; i < argc; i++) { mparse_reset(mp); - pmandoc(mp, -1, argv[i], list); + if (mparse_open(mp, &fd, argv[i]) != MANDOCLEVEL_OK) { + perror(argv[i]); + continue; + } + pmandoc(mp, fd, argv[i], list); } mparse_free(mp); @@ -108,11 +112,7 @@ pmandoc(struct mparse *mp, int fd, const struct man *man; int line, col; - if (mparse_readfd(mp, fd, fn) >= MANDOCLEVEL_FATAL) { - fprintf(stderr, "%s: Parse failure\n", fn); - return; - } - + mparse_readfd(mp, fd, fn); mparse_result(mp, &mdoc, &man, NULL); line = 1; col = 0; Index: man.1 =================================================================== RCS file: /home/cvs/mdocml/mdocml/man.1,v retrieving revision 1.10 retrieving revision 1.11 diff -Lman.1 -Lman.1 -u -p -r1.10 -r1.11 --- man.1 +++ man.1 @@ -3,7 +3,7 @@ .\" Copyright (c) 1989, 1990, 1993 .\" The Regents of the University of California. All rights reserved. .\" Copyright (c) 2003, 2007, 2008, 2014 Jason McIntyre -.\" Copyright (c) 2010, 2011 Ingo Schwarze +.\" Copyright (c) 2010, 2011, 2014, 2015 Ingo Schwarze .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions @@ -300,15 +300,15 @@ to be reported on the standard error out The .Ar level can be -.Cm warning , -.Cm error , +.Cm warning or -.Cm fatal . -The default is -.Cm fatal ; +.Cm error ; .Cm all is an alias for .Cm warning . +By default, +.Nm +is silent. See the .Xr mandoc 1 manual for details. Index: mdoc.c =================================================================== RCS file: /home/cvs/mdocml/mdocml/mdoc.c,v retrieving revision 1.233 retrieving revision 1.234 diff -Lmdoc.c -Lmdoc.c -u -p -r1.233 -r1.234 --- mdoc.c +++ mdoc.c @@ -190,12 +190,11 @@ mdoc_alloc(struct roff *roff, struct mpa return(p); } -int +void mdoc_endparse(struct mdoc *mdoc) { mdoc_macroend(mdoc); - return(1); } void Index: mandoc.1 =================================================================== RCS file: /home/cvs/mdocml/mdocml/mandoc.1,v retrieving revision 1.131 retrieving revision 1.132 diff -Lmandoc.1 -Lmandoc.1 -u -p -r1.131 -r1.132 --- mandoc.1 +++ mandoc.1 @@ -159,15 +159,15 @@ to be reported on the standard error out The .Ar level can be -.Cm warning , -.Cm error , +.Cm warning or -.Cm fatal . -The default is -.Fl W Ns Cm fatal ; -.Fl W Ns Cm all +.Cm error ; +.Cm all is an alias for -.Fl W Ns Cm warning . +.Cm warning . +By default, +.Nm +is silent. See .Sx EXIT STATUS and @@ -532,13 +532,11 @@ At least one warning occurred, but no er .Fl W Ns Cm warning was specified. .It 3 -At least one parsing error occurred, but no fatal error, and +At least one parsing error occurred, and .Fl W Ns Cm error or .Fl W Ns Cm warning was specified. -.It 4 -A fatal parsing error occurred. .It 5 Invalid command line arguments were specified. No input files have been read. @@ -603,9 +601,6 @@ fields. .Pp Message levels have the following meanings: .Bl -tag -width "warning" -.It Cm fatal -The parser is unable to parse a given input file at all. -No formatted output is produced from that input file. .It Cm error An input file contains syntax that cannot be safely interpreted, either because it is invalid or because @@ -1277,6 +1272,14 @@ keeps the code more readable. .El .Ss "Errors related to roff, mdoc, and man code" .Bl -ohang +.It Sy "input too large" +.Pq mdoc , man +Currently, +.Nm +cannot handle input files larger than its arbitrary size limit +of 2^31 bytes (2 Gigabytes). +Since useful manuals are always small, this is not a problem in practice. +Parsing is aborted as soon as the condition is detected. .It Sy "input stack limit exceeded, infinite loop?" .Pq roff Explicit recursion limits are implemented for the following features, @@ -1465,6 +1468,29 @@ or .Ic \&gsize statement has a non-numeric or negative argument or no argument at all. The invalid request or statement is ignored. +.It Sy "NOT IMPLEMENTED: .so with absolute path or \(dq..\(dq" +.Pq roff +For security reasons, +.Nm +allows +.Ic \&so +file inclusion requests only with relative paths +and only without ascending to any parent directory. +By requesting the inclusion of a sensitive file, a malicious document +might otherwise trick a privileged user into inadvertently displaying +the file on the screen, revealing the file content to bystanders. +.Nm +only shows the path as it appears behind +.Ic \&so . +.It Sy ".so request failed" +.Pq roff +Servicing a +.Ic \&so +request requires reading an external file, but the file could not be +opened. +.Nm +only shows the path as it appears behind +.Ic \&so . .It Sy "skipping all arguments" .Pq mdoc , man , eqn , roff An @@ -1503,44 +1529,6 @@ macro is invoked with more than one argu .Ic \&de family is invoked with more than two arguments. The excess arguments are ignored. -.El -.Ss FATAL errors -.Bl -ohang -.It Sy "input too large" -.Pq mdoc , man -Currently, -.Nm -cannot handle input files larger than its arbitrary size limit -of 2^31 bytes (2 Gigabytes). -Since useful manuals are always small, this is not a problem in practice. -Parsing is aborted as soon as the condition is detected. -.It Sy "NOT IMPLEMENTED: .so with absolute path or \(dq..\(dq" -.Pq roff -For security reasons, -.Nm -allows -.Ic \&so -file inclusion requests only with relative paths -and only without ascending to any parent directory. -By requesting the inclusion of a sensitive file, a malicious document -might otherwise trick a privileged user into inadvertently displaying -the file on the screen, revealing the file content to bystanders. -The parser exits immediately. -.It Sy ".so request failed" -.Pq roff -Servicing a -.Ic \&so -request requires reading an external file. -While trying to do so, an -.Xr open 2 , -.Xr stat 2 , -or -.Xr read 2 -system call failed. -The parser exits immediately. -Before showing this message, -.Nm -always shows another message explaining why the system call failed. .El .Sh COMPATIBILITY This section summarises Index: main.c =================================================================== RCS file: /home/cvs/mdocml/mdocml/main.c,v retrieving revision 1.214 retrieving revision 1.215 diff -Lmain.c -Lmain.c -u -p -r1.214 -r1.215 --- main.c +++ main.c @@ -176,7 +176,7 @@ main(int argc, char *argv[]) memset(&curp, 0, sizeof(struct curparse)); curp.outtype = OUTT_LOCALE; - curp.wlevel = MANDOCLEVEL_FATAL; + curp.wlevel = MANDOCLEVEL_BADARG; options = MPARSE_SO | MPARSE_UTF8 | MPARSE_LATIN1; defos = NULL; @@ -647,11 +647,6 @@ parse(struct curparse *curp, int fd, con rc = mparse_readfd(curp->mp, fd, file); - /* Stop immediately if the parse has failed. */ - - if (MANDOCLEVEL_FATAL <= rc) - goto cleanup; - /* * With -Wstop and warnings or errors of at least the requested * level, do not produce output. @@ -913,7 +908,7 @@ woptions(struct curparse *curp, char *ar curp->wlevel = MANDOCLEVEL_ERROR; break; case 4: - curp->wlevel = MANDOCLEVEL_FATAL; + curp->wlevel = MANDOCLEVEL_BADARG; break; default: fprintf(stderr, "%s: -W %s: Bad argument\n", Index: cgi.c =================================================================== RCS file: /home/cvs/mdocml/mdocml/cgi.c,v retrieving revision 1.102 retrieving revision 1.103 diff -Lcgi.c -Lcgi.c -u -p -r1.102 -r1.103 --- cgi.c +++ cgi.c @@ -822,7 +822,6 @@ format(const struct req *req, const char struct man *man; void *vp; char *opts; - enum mandoclevel rc; int fd; int usepath; @@ -832,17 +831,10 @@ format(const struct req *req, const char } mchars = mchars_alloc(); - mp = mparse_alloc(MPARSE_SO, MANDOCLEVEL_FATAL, NULL, + mp = mparse_alloc(MPARSE_SO, MANDOCLEVEL_BADARG, NULL, mchars, req->q.manpath); - rc = mparse_readfd(mp, fd, file); + mparse_readfd(mp, fd, file); close(fd); - - if (rc >= MANDOCLEVEL_FATAL) { - fprintf(stderr, "fatal mandoc error: %s/%s\n", - req->q.manpath, file); - pg_error_internal(); - return; - } usepath = strcmp(req->q.manpath, req->p[0]); mandoc_asprintf(&opts, Index: mandoc.3 =================================================================== RCS file: /home/cvs/mdocml/mdocml/mandoc.3,v retrieving revision 1.30 retrieving revision 1.31 diff -Lmandoc.3 -Lmandoc.3 -u -p -r1.30 -r1.31 --- mandoc.3 +++ mandoc.3 @@ -1,7 +1,7 @@ .\" $Id$ .\" .\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons -.\" Copyright (c) 2010 Ingo Schwarze +.\" Copyright (c) 2010, 2013, 2014, 2015 Ingo Schwarze .\" .\" Permission to use, copy, modify, and distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above @@ -39,11 +39,10 @@ .Nm mparse_strlevel .Nm mparse_wait , .Nd mandoc macro compiler library -.Sh LIBRARY -.Lb libmandoc .Sh SYNOPSIS .In sys/types.h .In mandoc.h +.Pp .Fd "#define ASCII_NBRSP" .Fd "#define ASCII_HYPH" .Fd "#define ASCII_BREAK" @@ -176,12 +175,15 @@ initiate a parsing sequence with and .Fn mparse_alloc ; .It -parse files with -.Fn mparse_open -and +open a file with +.Xr open 2 +or +.Fn mparse_open ; +.It +parse it with .Fn mparse_readfd ; .It -retrieve a parsed syntax tree, if the parse was successful, with +retrieve the syntax tree with .Fn mparse_result ; .It iterate over parse nodes with @@ -208,7 +210,7 @@ and .Ss Types .Bl -ohang .It Vt "enum mandocerr" -A fatal error, error, or warning message during parsing. +An error or warning message during parsing. .It Vt "enum mandoclevel" A classification of an .Vt "enum mandocerr" @@ -229,7 +231,7 @@ This may be used across parsed input if .Fn mparse_reset is called between parses. .It Vt "mandocmsg" -A prototype for a function to handle fatal error, error, and warning +A prototype for a function to handle error and warning messages emitted by the parser. .El .Ss Functions @@ -333,7 +335,7 @@ This is for example useful in to quickly build minimal databases. .It Ar wlevel Can be set to -.Dv MANDOCLEVEL_FATAL , +.Dv MANDOCLEVEL_BADARG , .Dv MANDOCLEVEL_ERROR , or .Dv MANDOCLEVEL_WARNING . @@ -441,14 +443,7 @@ implemented in .Pa read.c . .It Fn mparse_result Obtain the result of a parse. -Only successful parses -.Po -i.e., those where -.Fn mparse_readfd -returned less than MANDOCLEVEL_FATAL -.Pc -should invoke this function, in which case one of the three pointers will -be filled in. +One of the three pointers will be filled in. Declared in .In mandoc.h , implemented in Index: mandocdb.c =================================================================== RCS file: /home/cvs/mdocml/mdocml/mandocdb.c,v retrieving revision 1.182 retrieving revision 1.183 diff -Lmandocdb.c -Lmandocdb.c -u -p -r1.182 -r1.183 --- mandocdb.c +++ mandocdb.c @@ -442,7 +442,7 @@ mandocdb(int argc, char *argv[]) exitcode = (int)MANDOCLEVEL_OK; mchars = mchars_alloc(); - mp = mparse_alloc(mparse_options, MANDOCLEVEL_FATAL, NULL, + mp = mparse_alloc(mparse_options, MANDOCLEVEL_BADARG, NULL, mchars, NULL); ohash_init(&mpages, 6, &mpages_info); ohash_init(&mlinks, 6, &mlinks_info); @@ -1102,7 +1102,6 @@ mpages_merge(struct mparse *mp) char *cp; int fd; unsigned int pslot; - enum mandoclevel lvl; str_info.alloc = hash_alloc; str_info.calloc = hash_calloc; @@ -1136,14 +1135,12 @@ mpages_merge(struct mparse *mp) } /* - * Try interpreting the file as mdoc(7) or man(7) - * source code, unless it is already known to be - * formatted. Fall back to formatted mode. + * Interpret the file as mdoc(7) or man(7) source + * code, unless it is known to be formatted. */ if (mlink->dform != FORM_CAT || mlink->fform != FORM_CAT) { - lvl = mparse_readfd(mp, fd, mlink->file); - if (lvl < MANDOCLEVEL_FATAL) - mparse_result(mp, &mdoc, &man, &sodest); + mparse_readfd(mp, fd, mlink->file); + mparse_result(mp, &mdoc, &man, &sodest); } if (sodest != NULL) { Index: read.c =================================================================== RCS file: /home/cvs/mdocml/mdocml/read.c,v retrieving revision 1.110 retrieving revision 1.111 diff -Lread.c -Lread.c -u -p -r1.110 -r1.111 --- read.c +++ read.c @@ -80,7 +80,7 @@ static const enum mandocerr mandoclimits MANDOCERR_WARNING, MANDOCERR_WARNING, MANDOCERR_ERROR, - MANDOCERR_FATAL, + MANDOCERR_MAX, MANDOCERR_MAX, MANDOCERR_MAX }; @@ -192,6 +192,7 @@ static const char * const mandocerrs[MAN /* related to document structure and macros */ NULL, + "input too large", "input stack limit exceeded, infinite loop?", "skipping bad character", "skipping unknown macro", @@ -215,10 +216,6 @@ static const char * const mandocerrs[MAN "skipping all arguments", "skipping excess arguments", "divide by zero", - - "generic fatal error", - - "input too large", }; static const char * const mandoclevels[MANDOCLEVEL_MAX] = { @@ -545,14 +542,6 @@ rerun: } /* - * If we encounter errors in the recursive parse, make - * sure we don't continue parsing. - */ - - if (MANDOCLEVEL_FATAL <= curp->file_status) - break; - - /* * If input parsers have not been allocated, do so now. * We keep these instanced between parsers, but set them * locally per parse routine since we can use different @@ -623,10 +612,7 @@ read_whole_file(struct mparse *curp, con if (S_ISREG(st.st_mode)) { if (st.st_size >= (1U << 31)) { - curp->file_status = MANDOCLEVEL_FATAL; - if (curp->mmsg) - (*curp->mmsg)(MANDOCERR_TOOLARGE, - curp->file_status, file, 0, 0, NULL); + mandoc_msg(MANDOCERR_TOOLARGE, curp, 0, 0, NULL); return(0); } *with_mmap = 1; @@ -649,11 +635,8 @@ read_whole_file(struct mparse *curp, con for (;;) { if (off == fb->sz) { if (fb->sz == (1U << 31)) { - curp->file_status = MANDOCLEVEL_FATAL; - if (curp->mmsg) - (*curp->mmsg)(MANDOCERR_TOOLARGE, - curp->file_status, - file, 0, 0, NULL); + mandoc_msg(MANDOCERR_TOOLARGE, curp, + 0, 0, NULL); break; } resize_buf(fb, 65536); @@ -679,9 +662,6 @@ static void mparse_end(struct mparse *curp) { - if (MANDOCLEVEL_FATAL <= curp->file_status) - return; - if (curp->mdoc == NULL && curp->man == NULL && curp->sodest == NULL) { @@ -695,17 +675,10 @@ mparse_end(struct mparse *curp) curp->man = curp->pman; } } - - if (curp->mdoc && ! mdoc_endparse(curp->mdoc)) { - assert(MANDOCLEVEL_FATAL <= curp->file_status); - return; - } - - if (curp->man && ! man_endparse(curp->man)) { - assert(MANDOCLEVEL_FATAL <= curp->file_status); - return; - } - + if (curp->mdoc) + mdoc_endparse(curp->mdoc); + if (curp->man) + man_endparse(curp->man); roff_endparse(curp->roff); } @@ -742,7 +715,7 @@ mparse_parse_buffer(struct mparse *curp, mparse_buf_r(curp, blk, offset, 1); - if (0 == --recursion_depth && MANDOCLEVEL_FATAL > curp->file_status) + if (--recursion_depth == 0) mparse_end(curp); curp->primary = svprimary; @@ -889,8 +862,6 @@ mparse_alloc(int options, enum mandoclev { struct mparse *curp; - assert(wlevel <= MANDOCLEVEL_FATAL); - curp = mandoc_calloc(1, sizeof(struct mparse)); curp->options = options; @@ -987,7 +958,7 @@ mandoc_msg(enum mandocerr er, struct mpa { enum mandoclevel level; - level = MANDOCLEVEL_FATAL; + level = MANDOCLEVEL_ERROR; while (er < mandoclimits[level]) level--; Index: mandoc.h =================================================================== RCS file: /home/cvs/mdocml/mdocml/mandoc.h,v retrieving revision 1.181 retrieving revision 1.182 diff -Lmandoc.h -Lmandoc.h -u -p -r1.181 -r1.182 --- mandoc.h +++ mandoc.h @@ -148,6 +148,7 @@ enum mandocerr { /* related to document structure and macros */ MANDOCERR_FILE, /* cannot open file */ + MANDOCERR_TOOLARGE, /* input too large */ MANDOCERR_ROFFLOOP, /* input stack limit exceeded, infinite loop? */ MANDOCERR_BADCHAR, /* skipping bad character: number */ MANDOCERR_MACRO, /* skipping unknown macro: macro */ @@ -171,10 +172,6 @@ enum mandocerr { MANDOCERR_ARG_SKIP, /* skipping all arguments: macro args */ MANDOCERR_ARG_EXCESS, /* skipping excess arguments: macro ... args */ MANDOCERR_DIVZERO, /* divide by zero */ - - MANDOCERR_FATAL, /* ===== start of fatal errors ===== */ - - MANDOCERR_TOOLARGE, /* input too large */ MANDOCERR_MAX }; Index: man.c =================================================================== RCS file: /home/cvs/mdocml/mdocml/man.c,v retrieving revision 1.146 retrieving revision 1.147 diff -Lman.c -Lman.c -u -p -r1.146 -r1.147 --- man.c +++ man.c @@ -109,12 +109,11 @@ man_alloc(struct roff *roff, struct mpar return(p); } -int +void man_endparse(struct man *man) { man_macroend(man); - return(1); } int -- To unsubscribe send an email to source+unsubscribe@mdocml.bsd.lv