Skip to content

Commit

Permalink
* JSON errors are now labelled with JSON and not XML
Browse files Browse the repository at this point in the history
* Fixed: [Performance issue when parsing large JSON param](#266)
* Moved strlen() from for end condition
* Fixed debugging of xpath parser
  • Loading branch information
olofhagsand committed Sep 20, 2021
1 parent 3cd3f79 commit 392e667
Show file tree
Hide file tree
Showing 17 changed files with 166 additions and 89 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ Users may have to change how they access the system

### Minor features

* JSON errors are now labelled with JSON and not XML
* Restconf native HTTP/2:
* Added option `CLICON_RESTCONF_HTTP2_PLAIN` for non-TLS http
* Default disabled, set to true to enable HTTP/2 direct and switch/upgrade HTTP/1->HTTP/2
Expand All @@ -78,6 +79,7 @@ Users may have to change how they access the system

### Corrected Bugs

* Fixed: [Performance issue when parsing large JSON param](https://github.com/clicon/clixon/issues/266)
* Fixed: [Duplicate lines emitted by cli_show_config (cli output style) when yang list element has composite key](https://github.com/clicon/clixon/issues/258)
* Fixed: [JSON leaf-list output single element leaf-list does not use array](https://github.com/clicon/clixon/issues/261)
* Fixed: Netconf diff callback did not work with choice and same value replace
Expand Down
4 changes: 3 additions & 1 deletion apps/cli/cli_auto.c
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,7 @@ cli_auto_up(clicon_handle h,
char *api_path = NULL;
int i;
int j;
size_t len;

if (cvec_len(argv) != 1){
clicon_err(OE_PLUGIN, EINVAL, "Usage: %s(<treename>)", __FUNCTION__);
Expand Down Expand Up @@ -551,7 +552,8 @@ cli_auto_up(clicon_handle h,
/* Find diff of 0 and 1 (how many variables differ?) and trunc cvv0 by that amount */
cvv0 = clicon_data_cvec_get(h, "cli-edit-cvv");
j=0; /* count diffs */
for (i=strlen(api_path_fmt1); i<strlen(api_path_fmt0); i++)
len = strlen(api_path_fmt0);
for (i=strlen(api_path_fmt1); i<len; i++)
if (api_path_fmt0[i] == '%')
j++;
cvv1 = cvec_new(0);
Expand Down
4 changes: 3 additions & 1 deletion apps/cli/cli_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -1210,6 +1210,7 @@ cli_copy_config(clicon_handle h,
char *toname;
cxobj *xerr;
cvec *nsc = NULL;
size_t len;

if (cvec_len(argv) != 6){
clicon_err(OE_PLUGIN, EINVAL, "Requires 6 elements: <db> <xpath> <namespace> <keyname> <from> <to>");
Expand Down Expand Up @@ -1241,8 +1242,9 @@ cli_copy_config(clicon_handle h,
goto done;
}
/* Sanity check that xpath contains exactly two %s, ie [%s='%s'] */
len = strlen(xpath);
j = 0;
for (i=0; i<strlen(xpath); i++){
for (i=0; i<len; i++){
if (xpath[i] == '%')
j++;
}
Expand Down
4 changes: 3 additions & 1 deletion apps/cli/cli_generate.c
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,7 @@ yang2cli_var_sub(clicon_handle h,
int j;
char *cvtypestr;
char *arg;
size_t len;

if (cvtype == CGV_VOID){
retval = 0;
Expand All @@ -428,7 +429,8 @@ yang2cli_var_sub(clicon_handle h,
cprintf(cb, "|");
/* Encode by escaping delimiters */
arg = yang_argument_get(yi);
for (j=0; j<strlen(arg); j++){
len = strlen(arg);
for (j=0; j<len; j++){
if (index(CLIGEN_DELIMITERS, arg[j]))
cprintf(cb, "\\");
cprintf(cb, "%c", arg[j]);
Expand Down
4 changes: 3 additions & 1 deletion apps/restconf/restconf_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -287,14 +287,16 @@ restconf_convert_hdr(clicon_handle h,
cbuf *cb = NULL;
int i;
char c;
size_t len;

if ((cb = cbuf_new()) == NULL){
clicon_err(OE_UNIX, errno, "cbuf_new");
goto done;
}
/* convert key name */
cprintf(cb, "HTTP_");
for (i=0; i<strlen(name); i++){
len = strlen(name);
for (i=0; i<len; i++){
c = name[i] & 0xff;
if (islower(c))
cprintf(cb, "%c", toupper(c));
Expand Down
4 changes: 3 additions & 1 deletion apps/restconf/restconf_methods_patch.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ yang_patch_xml2json_modified_cbuf(cxobj *x_simple_patch)
cbuf *cb = NULL;
char *json_simple_patch_tmp;
int brace_count = 0;
size_t len;

json_simple_patch = cbuf_new();
if (json_simple_patch == NULL)
Expand All @@ -122,7 +123,8 @@ yang_patch_xml2json_modified_cbuf(cxobj *x_simple_patch)

// Insert a '[' after the first '{' to get the JSON to match what api_data_post/write() expect
json_simple_patch_tmp = cbuf_get(cb);
for (int l = 0; l < strlen(json_simple_patch_tmp); l++) {
len = strlen(json_simple_patch_tmp);
for (int l = 0; l < strlen(len); l++) {
char c = json_simple_patch_tmp[l];
if (c == '{') {
brace_count++;
Expand Down
4 changes: 2 additions & 2 deletions lib/clixon/clixon_err.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ enum clicon_err{
OE_UNIX, /* unix/linux syscall error */
OE_SYSLOG, /* syslog error */
OE_ROUTING, /* routing daemon error (eg quagga) */
OE_XML, /* xml parsing etc */

OE_XML, /* xml parsing */
OE_JSON, /* json parsing */
OE_RESTCONF, /* RESTCONF errors */
OE_PLUGIN, /* plugin loading, etc */
OE_YANG , /* Yang error */
Expand Down
3 changes: 3 additions & 0 deletions lib/clixon/clixon_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,9 @@ typedef int (plgreset_t)(clicon_handle h, const char *db);
*/
typedef int (plgstatedata_t)(clicon_handle h, cvec *nsc, char *xpath, cxobj *xtop);

/* Transaction-data type
* @see clixon_backend_transaction.h for full transaction API
*/
typedef void *transaction_data;

/* Transaction callback */
Expand Down
1 change: 1 addition & 0 deletions lib/src/clixon_err.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ static struct errvec EV[] = {
{"Syslog error", OE_SYSLOG},
{"Routing demon error", OE_ROUTING},
{"XML error", OE_XML},
{"JSON error", OE_JSON},
{"RESTCONF error", OE_RESTCONF},
{"Plugins", OE_PLUGIN},
{"Yang error", OE_YANG},
Expand Down
18 changes: 10 additions & 8 deletions lib/src/clixon_json.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,8 +257,10 @@ json_str_escape_cdata(cbuf *cb,
int retval = -1;
int i;
int esc = 0; /* cdata escape */
size_t len;

for (i=0;i<strlen(str);i++)
len = strlen(str);
for (i=0; i<len; i++)
switch (str[i]){
case '\n':
cprintf(cb, "\\n");
Expand Down Expand Up @@ -372,7 +374,7 @@ json2xml_decode_identityref(cxobj *x,
/* Here prefix2 is valid and can be NULL
Change body prefix to prefix2:id */
if ((cbv = cbuf_new()) == NULL){
clicon_err(OE_XML, errno, "cbuf_new");
clicon_err(OE_JSON, errno, "cbuf_new");
goto done;
}
if (prefix2)
Expand Down Expand Up @@ -1245,7 +1247,7 @@ _json_parse(char *str,
if (clixon_json_parseparse(&jy) != 0) { /* yacc returns 1 on error */
clicon_log(LOG_NOTICE, "JSON error: line %d", jy.jy_linenum);
if (clicon_errno == 0)
clicon_err(OE_XML, 0, "JSON parser error with no error code (should not happen)");
clicon_err(OE_JSON, 0, "JSON parser error with no error code (should not happen)");
goto done;
}
/* Traverse new objects */
Expand Down Expand Up @@ -1361,7 +1363,7 @@ clixon_json_parse_string(char *str,
{
clicon_debug(1, "%s", __FUNCTION__);
if (xt==NULL){
clicon_err(OE_XML, EINVAL, "xt is NULL");
clicon_err(OE_JSON, EINVAL, "xt is NULL");
return -1;
}
if (*xt == NULL){
Expand Down Expand Up @@ -1422,18 +1424,18 @@ clixon_json_parse_file(FILE *fp,
int len = 0;

if (xt==NULL){
clicon_err(OE_XML, EINVAL, "xt is NULL");
clicon_err(OE_JSON, EINVAL, "xt is NULL");
return -1;
}
if ((jsonbuf = malloc(jsonbuflen)) == NULL){
clicon_err(OE_XML, errno, "malloc");
clicon_err(OE_JSON, errno, "malloc");
goto done;
}
memset(jsonbuf, 0, jsonbuflen);
ptr = jsonbuf;
while (1){
if ((ret = fread(&ch, 1, 1, fp)) < 0){
clicon_err(OE_XML, errno, "read");
clicon_err(OE_JSON, errno, "read");
break;
}
if (ret != 0)
Expand All @@ -1454,7 +1456,7 @@ clixon_json_parse_file(FILE *fp,
oldjsonbuflen = jsonbuflen;
jsonbuflen *= 2;
if ((jsonbuf = realloc(jsonbuf, jsonbuflen)) == NULL){
clicon_err(OE_XML, errno, "realloc");
clicon_err(OE_JSON, errno, "realloc");
goto done;
}
memset(jsonbuf+oldjsonbuflen, 0, jsonbuflen-oldjsonbuflen);
Expand Down
22 changes: 10 additions & 12 deletions lib/src/clixon_json_parse.y
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ object.
%union {
int intval;
char *string;
void *cbuf;
}

%token <string> J_FALSE
Expand All @@ -89,8 +90,8 @@ object.
%token <string> J_CHAR
%token <string> J_NUMBER

%type <string> string
%type <string> ustring
%type <cbuf> string
%type <cbuf> ustring
%type <string> number

%lex-param {void *_jy} /* Add this argument to parse() and lex() function */
Expand All @@ -102,7 +103,7 @@ object.
/* typecast macro */
#define _JY ((clixon_json_yacc *)_jy)

#define _YYERROR(msg) {clicon_err(OE_XML, 0, "YYERROR %s '%s' %d", (msg), clixon_json_parsetext, _JY->jy_linenum); YYERROR;}
#define _YYERROR(msg) {clicon_err(OE_JSON, 0, "YYERROR %s '%s' %d", (msg), clixon_json_parsetext, _JY->jy_linenum); YYERROR;}

/* add _yy to error parameters */
#define YY_(msgid) msgid
Expand Down Expand Up @@ -150,7 +151,7 @@ void
clixon_json_parseerror(void *_jy,
char *s)
{
clicon_err(OE_XML, XMLPARSE_ERRNO, "json_parse: line %d: %s at or before: '%s'",
clicon_err(OE_JSON, XMLPARSE_ERRNO, "json_parse: line %d: %s at or before: '%s'",
_JY->jy_linenum ,
s,
clixon_json_parsetext);
Expand Down Expand Up @@ -265,7 +266,7 @@ value : J_TRUE { json_current_body(_JY, "true"); _PARSE_DEBUG("va
| object { _PARSE_DEBUG("value->object"); }
| array { _PARSE_DEBUG("value->array"); }
| number { json_current_body(_JY, $1); free($1); _PARSE_DEBUG("value->number");}
| string { json_current_body(_JY, $1); free($1); _PARSE_DEBUG("value->string");}
| string { json_current_body(_JY, cbuf_get($1)); cbuf_free($1); _PARSE_DEBUG("value->string");}

;

Expand All @@ -277,7 +278,7 @@ objlist : pair { _PARSE_DEBUG("objlist->pair");}
| objlist ',' pair { _PARSE_DEBUG("objlist->objlist , pair");}
;

pair : string { json_current_new(_JY, $1);free($1);} ':'
pair : string { json_current_new(_JY, cbuf_get($1));cbuf_free($1);} ':'
value { json_current_pop(_JY);}{ _PARSE_DEBUG("pair->string : value");}
;

Expand All @@ -292,19 +293,16 @@ valuelist : value { _PARSE_DEBUG("valuelist->value"); }

/* quoted string */
string : J_DQ ustring J_DQ { _PARSE_DEBUG("string->\" ustring \"");$$=$2; }
| J_DQ J_DQ { _PARSE_DEBUG("string->\" \"");$$=strdup(""); }
| J_DQ J_DQ { _PARSE_DEBUG("string->\" \"");$$=cbuf_new(); }
;

/* unquoted string: can be optimized by reading whole string in lex */
ustring : ustring J_CHAR
{
int len = strlen($1);
$$ = realloc($1, len+strlen($2) + 1);
sprintf($$+len, "%s", $2);
free($2);
cbuf_append_str($1,$2); $$=$1; free($2);
}
| J_CHAR
{$$=$1;}
{ cbuf *cb = cbuf_new(); cbuf_append_str(cb,$1); $$=cb; free($1);}
;

number : J_NUMBER { $$ = $1; }
Expand Down
8 changes: 6 additions & 2 deletions lib/src/clixon_path.c
Original file line number Diff line number Diff line change
Expand Up @@ -460,13 +460,15 @@ api_path_fmt2api_path(const char *api_path_fmt,
char *str;
char *strenc=NULL;
cg_var *cv;
size_t len;

if ((cb = cbuf_new()) == NULL){
clicon_err(OE_UNIX, errno, "cbuf_new");
goto done;
}
j = 1; /* j==0 is cli string */
for (i=0; i<strlen(api_path_fmt); i++){
len = strlen(api_path_fmt);
for (i=0; i<len; i++){
c = api_path_fmt[i];
if (esc){
esc = 0;
Expand Down Expand Up @@ -546,13 +548,15 @@ api_path_fmt2xpath(char *api_path_fmt,
int j;
char *str;
cg_var *cv;
size_t len;

if ((cb = cbuf_new()) == NULL){
clicon_err(OE_UNIX, errno, "cbuf_new");
goto done;
}
j = 1; /* j==0 is cli string */
for (i=0; i<strlen(api_path_fmt); i++){
len = strlen(api_path_fmt);
for (i=0; i<len; i++){
c = api_path_fmt[i];
if (esc){
esc = 0;
Expand Down
6 changes: 4 additions & 2 deletions lib/src/clixon_regex.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,15 @@ regexp_xsd2posix(char *xsd,
int j; /* lookahead */
int esc;
int minus = 0;

size_t len;

if ((cb = cbuf_new()) == NULL){
clicon_err(OE_UNIX, errno, "cbuf_new");
goto done;
}
esc=0;
for (i=0; i<strlen(xsd); i++){
len = strlen(xsd);
for (i=0; i<len; i++){
x = xsd[i];
if (esc){
esc = 0;
Expand Down
Loading

0 comments on commit 392e667

Please sign in to comment.