* HTTP/1 native parser as part of the RESTCONF client

* Fixed memory error in opendir/readdir in clicon_file_dirent
* Remove MAXPATH in parsers
* New string-del function
This commit is contained in:
Olof hagsand 2022-01-26 13:48:20 +01:00
parent 0ed34b4fab
commit dadf4a778a
53 changed files with 1061 additions and 1273 deletions

View file

@ -82,8 +82,6 @@
/* typecast macro */
#define _AY ((clixon_api_path_yacc *)_ay)
#define MAXBUF 4*4*64*1024
#undef clixon_api_path_parsewrap
int
clixon_api_path_parsewrap(void)

View file

@ -172,6 +172,11 @@ clicon_files_recursive(const char *dir,
* do something with dp[i].d_name;
* free(dp);
* @endcode
* @note "ent" is an array with n fixed entries
* But this is not what is returned from the syscall, see man readdir:
* ... the use sizeof(struct dirent) to capture the size of the record including
* the size of d_name is also incorrect.
* @note May block on file I/O
*/
int
clicon_file_dirent(const char *dir,
@ -180,7 +185,7 @@ clicon_file_dirent(const char *dir,
mode_t type)
{
int retval = -1;
DIR *dirp;
DIR *dirp = NULL;
int res;
int nent;
regex_t re;
@ -188,11 +193,8 @@ clicon_file_dirent(const char *dir,
char filename[MAXPATHLEN];
struct stat st;
struct dirent *dent;
struct dirent *tmp;
struct dirent *new = NULL;
#if 0 /* revert of https://github.com/clicon/clixon/pull/238 */
int direntStructSize;
#endif
*ent = NULL;
nent = 0;
@ -225,25 +227,18 @@ clicon_file_dirent(const char *dir,
if ((type & st.st_mode) == 0)
continue;
}
#if 0 /* revert of https://github.com/clicon/clixon/pull/238 */
direntStructSize = offsetof(struct dirent, d_name) + strlen(dent->d_name) + 1;
clicon_debug(1, "%s %u %u %lu", __FUNCTION__, nent, direntStructSize, sizeof(struct dirent));
if ((tmp = realloc(new, (nent+1)*direntStructSize)) == NULL) {
#else
if ((tmp = realloc(new, (nent+1)*sizeof(struct dirent))) == NULL) {
#endif
if ((new = realloc(new, (nent+1)*sizeof(struct dirent))) == NULL) {
clicon_err(OE_UNIX, errno, "realloc");
goto quit;
}
new = tmp;
#if 0 /* revert of https://github.com/clicon/clixon/pull/238 */
} /* realloc */
clicon_debug(1, "%s memcpy(%p %p %u", __FUNCTION__, &new[nent], dent, direntStructSize);
memcpy(&new[nent], dent, direntStructSize); /* XXX Invalid write of size 8 */
#else
memcpy(&new[nent], dent, sizeof(*dent));
#endif
/* man (3) readdir:
* By implication, the use sizeof(struct dirent) to capture the size of the record including
* the size of d_name is also incorrect. */
memset(&new[nent], 0, sizeof(struct dirent));
memcpy(&new[nent], dent, direntStructSize);
nent++;
} /* while */
qsort((void *)new, nent, sizeof(*new), clicon_file_dirent_sort);

View file

@ -79,8 +79,6 @@
/* typecast macro */
#define _IY ((clixon_instance_id_yacc *)_iy)
#define MAXBUF 4*4*64*1024
#undef clixon_instance_id_parsewrap
int
clixon_instance_id_parsewrap(void)

View file

@ -65,8 +65,6 @@
/* typecast macro */
#define _JY ((clixon_json_yacc *)_yy)
#define MAXBUF 4*4*64*1024
#undef clixon_json_parsewrap
int
clixon_json_parsewrap(void)

View file

@ -149,6 +149,39 @@ clicon_strjoin(int argc,
return str;
}
/*! Join two string with delimiter.
* @param[in] str1 string 1 (will be freed) (optional)
* @param[in] del delimiter string (not freed) cannot be NULL (but "")
* @param[in] str2 string 2 (will be freed)
* @see clicon_strjoin
*/
char*
clixon_string_del_join(char *str1,
char *del,
char *str2)
{
char *str;
int len;
len = strlen(str2) + 1;
if (str1)
len += strlen(str1);
len += strlen(del);
if ((str = malloc(len)) == NULL){
clicon_err(OE_UNIX, errno, "malloc");
return NULL;
}
if (str1){
snprintf(str, len, "%s%s%s", str1, del, str2);
free(str1);
}
else
snprintf(str, len, "%s%s", del, str2);
free(str2);
return str;
}
/*! Split a string once into two parts: prefix and suffix
* @param[in] string
* @param[in] delim
@ -564,7 +597,7 @@ xml_chardata_cbuf_append(cbuf *cb,
* @retval -1 error
* @code
* cvec *cvv = NULL;
* if (uri_str2cvec("a=b&c=d", ';', '=', 1, &cvv) < 0)
* if (uri_str2cvec("a=b&c=d", '&', '=', 1, &cvv) < 0)
* err;
* @endcode
*
@ -840,6 +873,7 @@ clicon_strcmp(char *s1,
return strcmp(s1, s2);
}
/*! strndup() for systems without it, such as xBSD
*/
#ifndef HAVE_STRNDUP
@ -908,4 +942,3 @@ main(int argc, char **argv)
}
#endif /* Test program */

View file

@ -640,8 +640,8 @@ clixon_xml_parse_file(FILE *fp,
int oldxmlbuflen;
int failed = 0;
if (xt==NULL){
clicon_err(OE_XML, EINVAL, "xt is NULL");
if (xt==NULL || fp == NULL){
clicon_err(OE_XML, EINVAL, "arg is NULL");
return -1;
}
if (yb == YB_MODULE && yspec == NULL){

View file

@ -69,8 +69,6 @@
/* typecast macro */
#define _XPY ((clixon_xpath_yacc *)_yy)
#define MAXBUF 4*4*64*1024
#undef clixon_xpath_parsewrap
int
clixon_xpath_parsewrap(void)

View file

@ -35,7 +35,7 @@
* @see https://tools.ietf.org/html/rfc6020 YANG 1.0
* @see https://tools.ietf.org/html/rfc7950 YANG 1.1
* @note differences in double quoted strings: 1.1 does not allow \x, but 1.0
* does (where x is not n|t|"|\). See mode DQESC
* does (where x is not n|t|<double quote)|\). See mode DQESC
*/
%{
@ -67,11 +67,6 @@
/* typecast macro */
#define _YY ((clixon_yang_yacc *)_yy)
#define MAXBUF 4*4*64*1024
#define MAX(x,y) ((x)>(y)?(x):(y))
#define MIN(x,y) ((x)<(y)?(x):(y))
#undef clixon_yang_parsewrap
int
clixon_yang_parsewrap(void)

View file

@ -78,7 +78,6 @@
%type <string> identifier_ref_str
%type <string> bool_str
/* rfc 6020 keywords
See also enum rfc_6020 in clicon_yang.h. There, the constants have Y_ prefix instead of K_
* Wanted to unify these (K_ and Y_) but gave up for several reasons:
@ -154,7 +153,6 @@
%token K_YANG_VERSION
%token K_YIN_ELEMENT
/* Deviate keywords
*/
%token D_NOT_SUPPORTED
@ -192,6 +190,7 @@
#include <cligen/cligen.h>
#include "clixon_queue.h"
#include "clixon_string.h"
#include "clixon_hash.h"
#include "clixon_handle.h"
#include "clixon_err.h"
@ -351,37 +350,6 @@ ysp_add_push(clixon_yang_yacc *yy,
return ys;
}
/*! Join two string with delimiter.
* @param[in] str1 string 1 (will be freed) (optional)
* @param[in] del delimiter string (not freed) cannot be NULL (but "")
* @param[in] str2 string 2 (will be freed)
*/
static char*
string_del_join(char *str1,
char *del,
char *str2)
{
char *str;
int len;
len = strlen(str2) + 1;
if (str1)
len += strlen(str1);
len += strlen(del);
if ((str = malloc(len)) == NULL){
clicon_err(OE_UNIX, errno, "malloc");
return NULL;
}
if (str1){
snprintf(str, len, "%s%s%s", str1, del, str2);
free(str1);
}
else
snprintf(str, len, "%s%s", del, str2);
free(str2);
return str;
}
%}
@ -1640,23 +1608,23 @@ deviate_replace_substmt : type_stmt { _PARSE_DEBUG("deviate-replace-subs
*
*/
unknown_stmt : ustring ':' ustring optsep ';'
{ char *id; if ((id=string_del_join($1, ":", $3)) == NULL) _YYERROR("unknown_stmt");
{ char *id; if ((id=clixon_string_del_join($1, ":", $3)) == NULL) _YYERROR("unknown_stmt");
if (ysp_add(_yy, Y_UNKNOWN, id, NULL) == NULL) _YYERROR("unknown_stmt");
_PARSE_DEBUG("unknown-stmt -> ustring : ustring ;");
}
| ustring ':' ustring sep string optsep ';'
{ char *id; if ((id=string_del_join($1, ":", $3)) == NULL) _YYERROR("unknown_stmt");
{ char *id; if ((id=clixon_string_del_join($1, ":", $3)) == NULL) _YYERROR("unknown_stmt");
if (ysp_add(_yy, Y_UNKNOWN, id, $5) == NULL){ _YYERROR("unknown_stmt"); }
_PARSE_DEBUG("unknown-stmt -> ustring : ustring sep string ;");
}
| ustring ':' ustring optsep
{ char *id; if ((id=string_del_join($1, ":", $3)) == NULL) _YYERROR("unknown_stmt");
{ char *id; if ((id=clixon_string_del_join($1, ":", $3)) == NULL) _YYERROR("unknown_stmt");
if (ysp_add_push(_yy, Y_UNKNOWN, id, NULL) == NULL) _YYERROR("unknown_stmt"); }
'{' yang_stmts '}'
{ if (ystack_pop(_yy) < 0) _YYERROR("unknown_stmt");
_PARSE_DEBUG("unknown-stmt -> ustring : ustring { yang-stmts }"); }
| ustring ':' ustring sep string optsep
{ char *id; if ((id=string_del_join($1, ":", $3)) == NULL) _YYERROR("unknown_stmt");
{ char *id; if ((id=clixon_string_del_join($1, ":", $3)) == NULL) _YYERROR("unknown_stmt");
if (ysp_add_push(_yy, Y_UNKNOWN, id, $5) == NULL) _YYERROR("unknown_stmt"); }
'{' yang_stmts '}'
{ if (ystack_pop(_yy) < 0) _YYERROR("unknown_stmt");
@ -1850,10 +1818,10 @@ ustring : ustring CHARS
;
abs_schema_nodeid : abs_schema_nodeid '/' node_identifier
{ if (($$=string_del_join($1, "/", $3)) == NULL) _YYERROR("abs_schema_nodeid");
{ if (($$=clixon_string_del_join($1, "/", $3)) == NULL) _YYERROR("abs_schema_nodeid");
_PARSE_DEBUG("absolute-schema-nodeid -> absolute-schema-nodeid / node-identifier"); }
| '/' node_identifier
{ if (($$=string_del_join(NULL, "/", $2)) == NULL) _YYERROR("abs_schema_nodeid");
{ if (($$=clixon_string_del_join(NULL, "/", $2)) == NULL) _YYERROR("abs_schema_nodeid");
_PARSE_DEBUG("absolute-schema-nodeid -> / node-identifier"); }
;
@ -1887,7 +1855,7 @@ desc_schema_nodeid : node_identifier
{ $$= $1;
_PARSE_DEBUG("descendant-schema-nodeid -> node_identifier"); }
| node_identifier abs_schema_nodeid
{ if (($$=string_del_join($1, "", $2)) == NULL) _YYERROR("desc_schema_nodeid");
{ if (($$=clixon_string_del_join($1, "", $2)) == NULL) _YYERROR("desc_schema_nodeid");
_PARSE_DEBUG("descendant-schema-nodeid -> node_identifier abs_schema_nodeid"); }
;
@ -1926,7 +1894,7 @@ node_identifier : IDENTIFIER
{ $$=$1;
_PARSE_DEBUG("identifier-ref-arg-str -> string"); }
| IDENTIFIER ':' IDENTIFIER
{ if (($$=string_del_join($1, ":", $3)) == NULL) _YYERROR("node_identifier");
{ if (($$=clixon_string_del_join($1, ":", $3)) == NULL) _YYERROR("node_identifier");
_PARSE_DEBUG("identifier-ref-arg-str -> prefix : string"); }
;