From: David Lamparter Date: Tue, 4 Jun 2019 15:07:57 +0000 (+0200) Subject: lib/clippy: error out on unsupported bits X-Git-Tag: base_7.2~235^2~2 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=3779776a39d81168b701b2cc2ce50a3b2331d3e8;p=mirror%2Ffrr.git lib/clippy: error out on unsupported bits clippy can't process #ifdef or similar bits inside of an argument list (e.g. within the braces of a DEFUN or DEFPY statement.) Improve error reporting to catch these cases instead of generating broken C code. Fixes: #3840 Signed-off-by: David Lamparter --- diff --git a/lib/clippy.c b/lib/clippy.c index 44dcc02eb8..cd8067f5eb 100644 --- a/lib/clippy.c +++ b/lib/clippy.c @@ -85,8 +85,6 @@ int main(int argc, char **argv) if (PyRun_AnyFile(fp, pyfile)) { if (PyErr_Occurred()) PyErr_Print(); - else - printf("unknown python failure (?)\n"); return 1; } Py_Finalize(); diff --git a/lib/defun_lex.l b/lib/defun_lex.l index 6c0805a4fa..19b06f51b8 100644 --- a/lib/defun_lex.l +++ b/lib/defun_lex.l @@ -163,7 +163,7 @@ static int yylex_clr(char **retbuf) return rv; } -static PyObject *get_args(void) +static PyObject *get_args(const char *filename, int lineno) { PyObject *pyObj = PyList_New(0); PyObject *pyArg = NULL; @@ -190,6 +190,13 @@ static PyObject *get_args(void) free(tval); continue; } + if (token == PREPROC) { + free(tval); + Py_DECREF(pyObj); + return PyErr_Format(PyExc_ValueError, + "%s:%d: cannot process CPP directive within argument list", + filename, lineno); + } if (token == SPECIAL) { if (depth == 1 && (tval[0] == ',' || tval[0] == ')')) { if (pyArg) @@ -244,7 +251,12 @@ PyObject *clippy_parse(PyObject *self, PyObject *args) case DEFUNNY: case INSTALL: case AUXILIARY: - pyArgs = get_args(); + pyArgs = get_args(filename, lineno); + if (!pyArgs) { + free(tval); + Py_DECREF(pyCont); + return NULL; + } pyItem = PyDict_New(); PyDict_SetItemString(pyItem, "type", PyUnicode_FromString(tval)); PyDict_SetItemString(pyItem, "args", pyArgs); @@ -260,6 +272,7 @@ PyObject *clippy_parse(PyObject *self, PyObject *args) pyItem = PyDict_New(); PyDict_SetItemString(pyItem, "type", PyUnicode_FromString("PREPROC")); PyDict_SetItemString(pyItem, "line", PyUnicode_FromString(tval)); + lineno--; break; } if (pyItem) { diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 18e84fef23..c6617d9d21 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -8717,9 +8717,17 @@ DEFUN (no_ip_pim_ucast_bsm, #if HAVE_BFDD > 0 DEFUN_HIDDEN( + ip_pim_bfd_param, + ip_pim_bfd_param_cmd, + "ip pim bfd (2-255) (50-60000) (50-60000)", + IP_STR + PIM_STR + "Enables BFD support\n" + "Detect Multiplier\n" + "Required min receive interval\n" + "Desired min transmit interval\n") #else DEFUN( -#endif /* HAVE_BFDD */ ip_pim_bfd_param, ip_pim_bfd_param_cmd, "ip pim bfd (2-255) (50-60000) (50-60000)", @@ -8729,6 +8737,7 @@ DEFUN( "Detect Multiplier\n" "Required min receive interval\n" "Desired min transmit interval\n") +#endif /* HAVE_BFDD */ { VTY_DECLVAR_CONTEXT(interface, ifp); int idx_number = 3; diff --git a/python/clidef.py b/python/clidef.py index f8d96115bd..68682eea6c 100644 --- a/python/clidef.py +++ b/python/clidef.py @@ -183,11 +183,25 @@ argblock = Template(''' }''') def process_file(fn, ofd, dumpfd, all_defun): + errors = 0 filedata = clippy.parse(fn) for entry in filedata['data']: if entry['type'].startswith('DEFPY') or (all_defun and entry['type'].startswith('DEFUN')): + if len(entry['args'][0]) != 1: + sys.stderr.write('%s:%d: DEFPY function name not parseable (%r)\n' % (fn, entry['lineno'], entry['args'][0])) + errors += 1 + continue + cmddef = entry['args'][2] + for i in cmddef: + if not (i.startswith('"') and i.endswith('"')): + sys.stderr.write('%s:%d: DEFPY command string not parseable (%r)\n' % (fn, entry['lineno'], cmddef)) + errors += 1 + cmddef = None + break + if cmddef is None: + continue cmddef = ''.join([i[1:-1] for i in cmddef]) graph = clippy.Graph(cmddef) @@ -251,6 +265,8 @@ def process_file(fn, ofd, dumpfd, all_defun): params['nonempty'] = len(argblocks) ofd.write(templ.substitute(params)) + return errors + if __name__ == '__main__': import argparse @@ -274,7 +290,9 @@ if __name__ == '__main__': if args.show: dumpfd = sys.stderr - process_file(args.cfile, ofd, dumpfd, args.all_defun) + errors = process_file(args.cfile, ofd, dumpfd, args.all_defun) + if errors != 0: + sys.exit(1) if args.o is not None: clippy.wrdiff(args.o, ofd, [args.cfile, os.path.realpath(__file__), sys.executable])