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 49f241f1 for ; Sun, 24 Mar 2019 18:49:29 -0500 (EST) Date: Sun, 24 Mar 2019 18:49:29 -0500 (EST) X-Mailinglist: mandoc-source Reply-To: source@mandoc.bsd.lv MIME-Version: 1.0 From: schwarze@mandoc.bsd.lv To: source@mandoc.bsd.lv Subject: docbook2mdoc: To avoid use after free, use TAILQ_FOREACH_SAFE(3) rather X-Mailer: activitymail 1.26, http://search.cpan.org/dist/activitymail/ Content-Type: text/plain; charset=utf-8 Message-ID: Log Message: ----------- To avoid use after free, use TAILQ_FOREACH_SAFE(3) rather than TAILQ_FOREACH(3) when deleting list elements during the iteration. Factor out some repeated code into a new function pnode_printtitle(). Where pnode_print() calls per-element pnode_print*() functions, call exactly one function per element and do everything that is required inside, making the huge function pnode_print() slightly smaller and the various pnode_print*() more self-contained. In particular, call pnode_unlinksub() as close as possible to the place where the processing justifying the deletion was done. Modified Files: -------------- docbook2mdoc: docbook2mdoc.c Revision Data ------------- Index: docbook2mdoc.c =================================================================== RCS file: /home/cvs/mdocml/docbook2mdoc/docbook2mdoc.c,v retrieving revision 1.70 retrieving revision 1.71 diff -Ldocbook2mdoc.c -Ldocbook2mdoc.c -u -p -r1.70 -r1.71 --- docbook2mdoc.c +++ docbook2mdoc.c @@ -757,13 +757,13 @@ pnode_printpara(struct parse *p, struct static void pnode_printrefsynopsisdiv(struct parse *p, struct pnode *pn) { - struct pnode *pp; + struct pnode *pp, *pq; - TAILQ_FOREACH(pp, &pn->childq, child) - if (pp->node == NODE_TITLE) { + TAILQ_FOREACH_SAFE(pp, &pn->childq, child, pq) + if (pp->node == NODE_TITLE) pnode_unlink(pp); - return; - } + + macro_line(p, "Sh SYNOPSIS"); } /* @@ -867,6 +867,7 @@ pnode_printciterefentry(struct parse *p, else macro_addnode(p, manvol, 0); macro_close(p); + pnode_unlinksub(pn); } static void @@ -891,6 +892,7 @@ pnode_printrefmeta(struct parse *p, stru else macro_addnode(p, manvol, 0); macro_close(p); + pnode_unlink(pn); } static void @@ -961,8 +963,8 @@ pnode_printmathfenced(struct parse *p, s putchar(','); pnode_print(p, pp); } - printf("right %s ", pnode_getattr_raw(pn, ATTRKEY_CLOSE, ")")); + pnode_unlinksub(pn); } /* @@ -995,6 +997,7 @@ pnode_printmath(struct parse *p, struct pp = TAILQ_NEXT(pp, child); pnode_print(p, pp); + pnode_unlinksub(pn); } static void @@ -1016,6 +1019,7 @@ pnode_printfuncprototype(struct parse *p pnode_printparamdef(p, pp); macro_line(p, "Fc"); + pnode_unlinksub(pn); } /* @@ -1051,6 +1055,7 @@ pnode_printarg(struct parse *p, struct p if (isrep && pp->node == NODE_TEXT) macro_addarg(p, "...", 0); } + pnode_unlinksub(pn); } static void @@ -1101,6 +1106,7 @@ pnode_printgroup(struct parse *p, struct } if (sv) macro_close(p); + pnode_unlinksub(pn); } static void @@ -1112,10 +1118,9 @@ pnode_printprologue(struct parse *p, str pnode_findfirst(p->root, NODE_REFMETA); macro_line(p, "Dd $Mdocdate" "$"); - if (pp != NULL) { + if (pp != NULL) pnode_printrefmeta(p, pp); - pnode_unlink(pp); - } else { + else { macro_open(p, "Dt"); macro_addarg(p, pnode_getattr_raw(p->root, ATTRKEY_ID, "UNKNOWN"), 0); @@ -1154,6 +1159,21 @@ pnode_printvarlistentry(struct parse *p, TAILQ_FOREACH(pp, &pn->childq, child) if (pp->node != NODE_TERM) pnode_print(p, pp); + pnode_unlinksub(pn); +} + +static void +pnode_printtitle(struct parse *p, struct pnode *pn) +{ + struct pnode *pp, *pq; + + TAILQ_FOREACH_SAFE(pp, &pn->childq, child, pq) { + if (pp->node == NODE_TITLE) { + pnode_printpara(p, pp); + pnode_print(p, pp); + pnode_unlink(pp); + } + } } static void @@ -1167,6 +1187,7 @@ pnode_printrow(struct parse *p, struct p pnode_print(p, pp); } macro_line(p, "El"); + pnode_unlink(pn); } static void @@ -1174,20 +1195,14 @@ pnode_printtable(struct parse *p, struct { struct pnode *pp; - TAILQ_FOREACH(pp, &pn->childq, child) { - if (pp->node == NODE_TITLE) { - pnode_printpara(p, pp); - pnode_print(p, pp); - pnode_unlink(pp); - } - } + pnode_printtitle(p, pn); macro_line(p, "Bl -ohang"); while ((pp = pnode_findfirst(pn, NODE_ROW)) != NULL) { macro_line(p, "It Table Row"); pnode_printrow(p, pp); - pnode_unlink(pp); } macro_line(p, "El"); + pnode_unlinksub(pn); } static void @@ -1195,13 +1210,7 @@ pnode_printlist(struct parse *p, struct { struct pnode *pp; - TAILQ_FOREACH(pp, &pn->childq, child) { - if (pp->node == NODE_TITLE) { - pnode_printpara(p, pp); - pnode_print(p, pp); - pnode_unlink(pp); - } - } + pnode_printtitle(p, pn); macro_argline(p, "Bl", pn->node == NODE_ORDEREDLIST ? "-enum" : "-bullet"); TAILQ_FOREACH(pp, &pn->childq, child) { @@ -1209,6 +1218,7 @@ pnode_printlist(struct parse *p, struct pnode_print(p, pp); } macro_line(p, "El"); + pnode_unlinksub(pn); } static void @@ -1216,13 +1226,7 @@ pnode_printvariablelist(struct parse *p, { struct pnode *pp; - TAILQ_FOREACH(pp, &pn->childq, child) { - if (pp->node == NODE_TITLE) { - pnode_printpara(p, pp); - pnode_print(p, pp); - pnode_unlink(pp); - } - } + pnode_printtitle(p, pn); macro_line(p, "Bl -tag -width Ds"); TAILQ_FOREACH(pp, &pn->childq, child) { if (pp->node == NODE_VARLISTENTRY) @@ -1231,6 +1235,7 @@ pnode_printvariablelist(struct parse *p, macro_nodeline(p, "It", pp); } macro_line(p, "El"); + pnode_unlinksub(pn); } /* @@ -1262,7 +1267,6 @@ pnode_print(struct parse *p, struct pnod return; case NODE_ARG: pnode_printarg(p, pn); - pnode_unlinksub(pn); break; case NODE_AUTHOR: macro_open(p, "An"); @@ -1275,7 +1279,6 @@ pnode_print(struct parse *p, struct pnod break; case NODE_CITEREFENTRY: pnode_printciterefentry(p, pn); - pnode_unlinksub(pn); break; case NODE_CITETITLE: macro_open(p, "%T"); @@ -1311,7 +1314,6 @@ pnode_print(struct parse *p, struct pnod break; case NODE_FUNCPROTOTYPE: pnode_printfuncprototype(p, pn); - pnode_unlinksub(pn); break; case NODE_FUNCSYNOPSISINFO: macro_open(p, "Fd"); @@ -1328,11 +1330,9 @@ pnode_print(struct parse *p, struct pnod break; case NODE_ITEMIZEDLIST: pnode_printlist(p, pn); - pnode_unlinksub(pn); break; case NODE_GROUP: pnode_printgroup(p, pn); - pnode_unlinksub(pn); break; case NODE_KEYSYM: macro_open(p, "Sy"); @@ -1355,7 +1355,6 @@ pnode_print(struct parse *p, struct pnod break; case NODE_MML_MFENCED: pnode_printmathfenced(p, pn); - pnode_unlinksub(pn); break; case NODE_MML_MROW: case NODE_MML_MI: @@ -1369,14 +1368,12 @@ pnode_print(struct parse *p, struct pnod case NODE_MML_MSUB: case NODE_MML_MSUP: pnode_printmath(p, pn); - pnode_unlinksub(pn); break; case NODE_OPTION: macro_open(p, "Fl"); break; case NODE_ORDEREDLIST: pnode_printlist(p, pn); - pnode_unlinksub(pn); break; case NODE_PARA: pnode_printpara(p, pn); @@ -1417,7 +1414,6 @@ pnode_print(struct parse *p, struct pnod break; case NODE_REFSYNOPSISDIV: pnode_printrefsynopsisdiv(p, pn); - macro_line(p, "Sh SYNOPSIS"); break; case NODE_PREFACE: case NODE_SECTION: @@ -1442,7 +1438,6 @@ pnode_print(struct parse *p, struct pnod case NODE_TABLE: case NODE_INFORMALTABLE: pnode_printtable(p, pn); - pnode_unlinksub(pn); break; case NODE_TEXT: bufclear(p); @@ -1501,11 +1496,9 @@ pnode_print(struct parse *p, struct pnod break; case NODE_VARIABLELIST: pnode_printvariablelist(p, pn); - pnode_unlinksub(pn); break; case NODE_VARLISTENTRY: pnode_printvarlistentry(p, pn); - pnode_unlinksub(pn); break; case NODE_VARNAME: macro_open(p, "Va"); -- To unsubscribe send an email to source+unsubscribe@mandoc.bsd.lv