X-Git-Url: http://ftp.carnet.hr/carnet-debian/scm?p=ossec-hids.git;a=blobdiff_plain;f=src%2Fos_xml%2Fos_xml.c;fp=src%2Fos_xml%2Fos_xml.c;h=d736f20efb2f5fef11c387e08ccf30edce731656;hp=9a3f9598dfdeef673a2ddddc253b3e023158c2d2;hb=789cbc8e52da68eba3517b920ef22e000cf3c9fd;hpb=ef70704f0b31b59bb719b884d6a99cb9e3e2044a diff --git a/src/os_xml/os_xml.c b/src/os_xml/os_xml.c index 9a3f959..d736f20 100755 --- a/src/os_xml/os_xml.c +++ b/src/os_xml/os_xml.c @@ -12,39 +12,31 @@ /* os_xml Library. */ - - -#include "shared.h" +#include +#include +#include +#include +#include #include "os_xml.h" +#include "os_xml_internal.h" -#define _R_CONFS '<' -#define _R_CONFE '>' -#define _R_EQUAL '=' -#define _R_COM '!' -#define _R_VAR '$' - -#define OPEN 51 -#define CLOSE 52 - -#define LEOF -2 /* Internal functions */ -int _oscomment(FILE *fp); -int _writecontent(char *str, unsigned int size, int parent, OS_XML *_lxml); -int _writememory(char *str, short int type, unsigned int size, - int parent, OS_XML *_lxml); -int _checkmemory(char *str,OS_XML *_lxml); -int _ReadElem(FILE *fp, int position, int parent, OS_XML *_lxml); -int _getattributes(FILE *fp,int parent,OS_XML *_lxml); - -void xml_error(OS_XML *_lxml, const char *msg,...) __attribute__((format(printf, 2, 3))); +static int _oscomment(FILE *fp) __attribute__((nonnull)); +static int _writecontent(const char *str, size_t size, unsigned int parent, OS_XML *_lxml) __attribute__((nonnull)); +static int _writememory(const char *str, XML_TYPE type, size_t size, + unsigned int parent, OS_XML *_lxml) __attribute__((nonnull)); +static int _xml_fgetc(FILE *fp) __attribute__((nonnull)); +static int _ReadElem(FILE *fp, unsigned int parent, OS_XML *_lxml) __attribute__((nonnull)); +static int _getattributes(FILE *fp, unsigned int parent,OS_XML *_lxml) __attribute__((nonnull)); +static void xml_error(OS_XML *_lxml, const char *msg,...) __attribute__((format(printf, 2, 3), nonnull)); /* Currently line */ -int _line; +static unsigned int _line; /* Local fgetc */ -int _xml_fgetc(FILE *fp) +static int _xml_fgetc(FILE *fp) { int c; c = fgetc(fp); @@ -55,9 +47,7 @@ int _xml_fgetc(FILE *fp) return(c); } -#define FGETC(fp) _xml_fgetc(fp) - -void xml_error(OS_XML *_lxml, const char *msg,...) +static void xml_error(OS_XML *_lxml, const char *msg,...) { #ifdef DEBUG time_t tm; @@ -67,17 +57,17 @@ void xml_error(OS_XML *_lxml, const char *msg,...) va_list args; va_start(args,msg); -#ifdef DEBUG +#ifdef DEBUG tm = time(NULL); p = localtime(&tm); - fprintf(stderr,"%d/%d/%d %d:%d:%d (LINE: %d)",p->tm_year+1900,p->tm_mon, + fprintf(stderr,"%d/%d/%d %d:%d:%d (LINE: %u)",p->tm_year+1900,p->tm_mon, p->tm_mday,p->tm_hour,p->tm_min,p->tm_sec,_line); vfprintf(stderr, msg, args); fprintf(stderr, "\n\n"); #endif - memset(_lxml->err,'\0', 128); - vsnprintf(_lxml->err,127,msg,args); + memset(_lxml->err,'\0', XML_ERR_LENGTH); + vsnprintf(_lxml->err,XML_ERR_LENGTH-1,msg,args); va_end(args); _lxml->err_line = _line; } @@ -89,37 +79,60 @@ void xml_error(OS_XML *_lxml, const char *msg,...) */ void OS_ClearXML(OS_XML *_lxml) { - int i; + unsigned int i; for(i=0;i<_lxml->cur;i++) { - if(_lxml->el[i]) - free(_lxml->el[i]); - if(_lxml->ct[i]) - free(_lxml->ct[i]); + free(_lxml->el[i]); + free(_lxml->ct[i]); } _lxml->cur = 0; + _lxml->fol = 0; _lxml->err_line = 0; + free(_lxml->el); + _lxml->el = NULL; + free(_lxml->ct); + _lxml->ct = NULL; + free(_lxml->rl); + _lxml->rl = NULL; + free(_lxml->tp); + _lxml->tp = NULL; + free(_lxml->ck); - free(_lxml->ln); - memset(_lxml->err,'\0', 128); + _lxml->ck = NULL; - return; + free(_lxml->ln); + _lxml->ln = NULL; + memset(_lxml->err,'\0', XML_ERR_LENGTH); } /* OS_ReadXML v0.1 * Read a XML file and generate the necessary structs. */ -int OS_ReadXML(char *file, OS_XML *_lxml) +int OS_ReadXML(const char *file, OS_XML *_lxml) { - int r,i; + int r; + unsigned int i; FILE *fp; + /* init xml strcuture */ + _lxml->cur = 0; + _lxml->fol = 0; + _lxml->el = NULL; + _lxml->ct = NULL; + _lxml->tp = NULL; + _lxml->rl = NULL; + _lxml->ck = NULL; + _lxml->ln = NULL; + + _lxml->err_line = 0; + memset(_lxml->err,'\0',XML_ERR_LENGTH); + fp = fopen(file,"r"); if(!fp) { @@ -127,22 +140,10 @@ int OS_ReadXML(char *file, OS_XML *_lxml) return(-2); } - _lxml->cur = 0; - _lxml->fol = 0; - _lxml->el = NULL; - _lxml->ct = NULL; - _lxml->tp = NULL; - _lxml->rl = NULL; - _lxml->ck = NULL; - _lxml->ln = NULL; - - _lxml->err_line = 0; - memset(_lxml->err,'\0',128); - /* Zeroing the line */ _line = 1; - if((r = _ReadElem(fp,0,0,_lxml)) < 0) /* First position */ + if((r = _ReadElem(fp,0,_lxml)) < 0) /* First position */ { if(r != LEOF) { @@ -155,7 +156,7 @@ int OS_ReadXML(char *file, OS_XML *_lxml) { if(_lxml->ck[i] == 0) { - xml_error(_lxml,"XMLERR: Element '%s' not closed\n", _lxml->el[i]); + xml_error(_lxml,"XMLERR: Element '%s' not closed.", _lxml->el[i]); fclose(fp); return(-1); } @@ -166,12 +167,12 @@ int OS_ReadXML(char *file, OS_XML *_lxml) } -int _oscomment(FILE *fp) +static int _oscomment(FILE *fp) { int c; if((c = fgetc(fp)) == _R_COM) { - while((c=FGETC(fp)) != EOF) + while((c=_xml_fgetc(fp)) != EOF) { if(c == _R_COM) { @@ -181,7 +182,7 @@ int _oscomment(FILE *fp) } else if(c == '-') /* W3C way of finish comments */ { - if((c = FGETC(fp)) == '-') + if((c = _xml_fgetc(fp)) == '-') { if((c = fgetc(fp)) == _R_CONFE) return(1); @@ -200,14 +201,14 @@ int _oscomment(FILE *fp) } -int _ReadElem(FILE *fp, int position, int parent, OS_XML *_lxml) +static int _ReadElem(FILE *fp, unsigned int parent, OS_XML *_lxml) { int c; unsigned int count = 0; unsigned int _currentlycont = 0; short int location = -1; - char prevv = 0; + int prevv = 0; char elem[XML_MAXSIZE +1]; char cont[XML_MAXSIZE +1]; char closedelem[XML_MAXSIZE +1]; @@ -218,7 +219,7 @@ int _ReadElem(FILE *fp, int position, int parent, OS_XML *_lxml) memset(cont,'\0',XML_MAXSIZE +1); memset(closedelem,'\0',XML_MAXSIZE +1); - while((c=FGETC(fp)) != EOF) + while((c=_xml_fgetc(fp)) != EOF) { if(c == '\\') prevv = c; @@ -232,7 +233,7 @@ int _ReadElem(FILE *fp, int position, int parent, OS_XML *_lxml) /* Max size */ if(count >= XML_MAXSIZE) { - xml_error(_lxml,"XML ERR: String overflow. Exiting."); + xml_error(_lxml,"XMLERR: String overflow."); return(-1); } @@ -243,7 +244,7 @@ int _ReadElem(FILE *fp, int position, int parent, OS_XML *_lxml) int r = 0; if((r = _oscomment(fp)) < 0) { - xml_error(_lxml,"XML ERR: Comment not closed. Bad XML."); + xml_error(_lxml,"XMLERR: Comment not closed."); return(-1); } else if(r == 1) @@ -257,8 +258,7 @@ int _ReadElem(FILE *fp, int position, int parent, OS_XML *_lxml) { if((c=fgetc(fp)) == '/') { - xml_error(_lxml,"XML ERR: Bad formed XML. Element " - "not opened"); + xml_error(_lxml,"XMLERR: Element not opened."); return(-1); } else @@ -269,22 +269,25 @@ int _ReadElem(FILE *fp, int position, int parent, OS_XML *_lxml) continue; } - else if((location == 0) && ((c == _R_CONFE) || (c == ' '))) + else if((location == 0) && ((c == _R_CONFE) || isspace(c))) { int _ge = 0; int _ga = 0; elem[count]='\0'; /* Removing the / at the end of the element name */ - if(elem[count -1] == '/') + if(count > 0 && elem[count -1] == '/') { _ge = '/'; elem[count -1] = '\0'; } - _writememory(elem, XML_ELEM, count+1, parent, _lxml); + if(_writememory(elem, XML_ELEM, count+1, parent, _lxml) < 0) + { + return(-1); + } _currentlycont=_lxml->cur-1; - if(c == ' ') + if(isspace(c)) { if((_ga = _getattributes(fp,parent,_lxml)) < 0) return(-1); @@ -293,7 +296,10 @@ int _ReadElem(FILE *fp, int position, int parent, OS_XML *_lxml) /* If the element is closed already (finished in />) */ if((_ge == '/') || (_ga == '/')) { - _writecontent("\0", 2, _currentlycont,_lxml); + if(_writecontent("\0", 2, _currentlycont,_lxml) < 0) + { + return(-1); + } _lxml->ck[_currentlycont] = 1; _currentlycont = 0; count = 0; @@ -318,16 +324,19 @@ int _ReadElem(FILE *fp, int position, int parent, OS_XML *_lxml) closedelem[count]='\0'; if(strcmp(closedelem,elem) != 0) { - xml_error(_lxml,"XML ERR: Element not closed: %s",elem); + xml_error(_lxml,"XMLERR: Element '%s' not closed.",elem); return(-1); } - _writecontent(cont,strlen(cont)+1,_currentlycont,_lxml); - _lxml->ck[_currentlycont]=1; + if(_writecontent(cont,strlen(cont)+1,_currentlycont,_lxml) < 0) + { + return(-1); + } + _lxml->ck[_currentlycont]=1; memset(elem,'\0',XML_MAXSIZE); memset(closedelem,'\0',XML_MAXSIZE); memset(cont,'\0',XML_MAXSIZE); _currentlycont = 0; - count = 0; + count = 0; location = -1; if(parent > 0) return(0); @@ -339,13 +348,13 @@ int _ReadElem(FILE *fp, int position, int parent, OS_XML *_lxml) cont[count] = '\0'; count = 0; location = 2; - } + } else { ungetc(c,fp); ungetc(_R_CONFS,fp); - if(_ReadElem(fp,position+1,parent+1,_lxml)< 0) + if(_ReadElem(fp,parent+1,_lxml)< 0) { return(-1); } @@ -355,11 +364,11 @@ int _ReadElem(FILE *fp, int position, int parent, OS_XML *_lxml) else { if(location == 0) - elem[count++] = c; + elem[count++] = (char) c; else if(location == 1) - cont[count++] = c; + cont[count++] = (char) c; else if(location == 2) - closedelem[count++] = c; + closedelem[count++] = (char) c; if((_R_CONFS == c) && (prevv != 0)) { @@ -370,35 +379,75 @@ int _ReadElem(FILE *fp, int position, int parent, OS_XML *_lxml) if(location == -1) return(LEOF); - xml_error(_lxml,"XML ERR: End of file and some elements were not closed"); + xml_error(_lxml,"XMLERR: End of file and some elements were not closed."); return(-1); -} +} -int _writememory(char *str, short int type, unsigned int size, - int parent, OS_XML *_lxml) +static int _writememory(const char *str, XML_TYPE type, size_t size, + unsigned int parent, OS_XML *_lxml) { + char **tmp; + int *tmp2; + unsigned int *tmp3; + XML_TYPE *tmp4; + /* Allocating for the element */ - _lxml->el = (char **)realloc(_lxml->el,(_lxml->cur+1)*sizeof(char *)); + tmp = (char **)realloc(_lxml->el,(_lxml->cur+1)*sizeof(char *)); + if(tmp == NULL) + { + goto fail; + } + _lxml->el = tmp; _lxml->el[_lxml->cur]=(char *)calloc(size,sizeof(char)); + if(_lxml->el[_lxml->cur] == NULL) + { + goto fail; + } strncpy(_lxml->el[_lxml->cur],str,size-1); - /* Allocating for the content */ - _lxml->ct = (char **)realloc(_lxml->ct,(_lxml->cur+1)*sizeof(char *)); + /* Allocating for the content */ + tmp = (char **)realloc(_lxml->ct,(_lxml->cur+1)*sizeof(char *)); + if(tmp == NULL) + { + goto fail; + } + _lxml->ct = tmp; + _lxml->ct[_lxml->cur] = NULL; /* Allocating for the type */ - _lxml->tp = realloc(_lxml->tp,(_lxml->cur+1)*sizeof(int)); - _lxml->tp[_lxml->cur] = type; + tmp4 = (XML_TYPE *) realloc(_lxml->tp,(_lxml->cur+1)*sizeof(XML_TYPE)); + if(tmp4 == NULL) + { + goto fail; + } + _lxml->tp = tmp4; + _lxml->tp[_lxml->cur] = type; /* Allocating for the relation */ - _lxml->rl = realloc(_lxml->rl,(_lxml->cur+1)*sizeof(int)); + tmp3 = (unsigned int *) realloc(_lxml->rl,(_lxml->cur+1)*sizeof(unsigned int)); + if(tmp3 == NULL) + { + goto fail; + } + _lxml->rl = tmp3; _lxml->rl[_lxml->cur] = parent; /* Allocating for the "check" */ - _lxml->ck = realloc(_lxml->ck,(_lxml->cur+1)*sizeof(int)); + tmp2 = (int *) realloc(_lxml->ck,(_lxml->cur+1)*sizeof(int)); + if(tmp2 == NULL) + { + goto fail; + } + _lxml->ck = tmp2; _lxml->ck[_lxml->cur] = 0; /* Allocating for the line */ - _lxml->ln = realloc(_lxml->ln,(_lxml->cur+1)*sizeof(int)); + tmp3 = (unsigned int *) realloc(_lxml->ln,(_lxml->cur+1)*sizeof(unsigned int)); + if(tmp3 == NULL) + { + goto fail; + } + _lxml->ln = tmp3; _lxml->ln[_lxml->cur] = _line; /* Attributes does not need to be closed */ @@ -413,43 +462,33 @@ int _writememory(char *str, short int type, unsigned int size, _lxml->cur++; return(0); + + fail: + snprintf(_lxml->err, XML_ERR_LENGTH, "XMLERR: Memory error."); + return(-1); } -int _writecontent(char *str, unsigned int size, int parent, OS_XML *_lxml) +static int _writecontent(const char *str, size_t size, unsigned int parent, OS_XML *_lxml) { _lxml->ct[parent]=(char *)calloc(size,sizeof(char)); + if( _lxml->ct[parent] == NULL) + { + snprintf(_lxml->err, XML_ERR_LENGTH, "XMLERR: Memory error."); + return(-1); + } strncpy(_lxml->ct[parent],str,size-1); return(0); } -int _checkmemory(char *str,OS_XML *_lxml) -{ - int i; - for(i=0;i<_lxml->cur;i++) - { - if(_lxml->ck[i] == 0) - { - if(strcmp(str,_lxml->el[i]) == 0) - { - _lxml->ck[i] = 1; - return(0); - } - else - continue; - } - } - return(-1); -} - /* getattributes (Internal function): v0.1: 2005/03/03 * Read the attributes of an element */ -int _getattributes(FILE *fp,int parent,OS_XML *_lxml) +static int _getattributes(FILE *fp, unsigned int parent,OS_XML *_lxml) { int location = 0; - int count = 0; + unsigned int count = 0; int c; int c_to_match = 0; @@ -459,41 +498,67 @@ int _getattributes(FILE *fp,int parent,OS_XML *_lxml) memset(attr,'\0',XML_MAXSIZE+1); memset(value,'\0',XML_MAXSIZE+1); - while((c=FGETC(fp)) != EOF) + while((c=_xml_fgetc(fp)) != EOF) { if(count >= XML_MAXSIZE) { attr[count-1] = '\0'; xml_error(_lxml, - "XMLERR: Overflow attempt at attribute '%s'.",attr); + "XMLERR: Overflow attempt at attribute '%.20s'.",attr); return(-1); } - else if((c == _R_CONFE) || (c == '/')) + else if((c == _R_CONFE) || ((location == 0) && (c == '/'))) { - if((location == 1)||((location == 0)&&(count > 0))) + if(location == 1) { xml_error(_lxml, "XMLERR: Attribute '%s' not closed.", attr); return(-1); } + else if((location == 0)&&(count > 0)) + { + xml_error(_lxml, "XMLERR: Attribute '%s' has no value.", + attr); + return(-1); + } else if(c == '/') return(c); else return(0); - } + } else if((location == 0)&&(c == '=')) { attr[count]='\0'; - c = FGETC(fp); + + /* check for already existent attribute with same name */ + unsigned int i = _lxml->cur - 1; + /* search attributes backwards in same parent */ + while(_lxml->rl[i] == parent && _lxml->tp[i] == XML_ATTR) + { + if(strcmp(_lxml->el[i], attr) == 0) + { + xml_error(_lxml, "XMLERR: Attribute '%s' already defined.", attr); + return(-1); + } + + /* continue with previous element */ + if(i==0) + { + break; + } + i--; + } + + c = _xml_fgetc(fp); if((c != '"')&&(c != '\'')) { unsigned short int _err=1; - if(c == ' ') + if(isspace(c)) { - while((c=FGETC(fp))!= EOF) + while((c=_xml_fgetc(fp))!= EOF) { - if(c == ' ') + if(isspace(c)) continue; else if((c == '"')||(c == '\'')) { @@ -515,37 +580,53 @@ int _getattributes(FILE *fp,int parent,OS_XML *_lxml) location = 1; count = 0; } - else if((location == 0)&&(c == ' ')) - continue; - + else if((location == 0)&&(isspace(c))) + { + if(count == 0) + { + continue; + } + else + { + xml_error(_lxml, "XMLERR: Attribute '%s' has no value.", attr); + return(-1); + } + } else if((location == 1)&&(c == c_to_match)) { value[count]='\0'; - location = 0; - c_to_match = 0; + /* dead code: + * location = 0; + * c_to_match = 0; + */ - _writememory(attr, XML_ATTR, strlen(attr)+1, - parent, _lxml); - _writecontent(value,count+1,_lxml->cur-1,_lxml); - c = FGETC(fp); - if(c == ' ') - return(_getattributes(fp,parent,_lxml)); - else if(c == _R_CONFE) - return(0); - else + if(_writememory(attr, XML_ATTR, strlen(attr)+1, + parent, _lxml) < 0) { - xml_error(_lxml, - "XMLERR: Bad attribute closing for '%s'='%s'.", - attr,value); return(-1); } - count = 0; + if(_writecontent(value,count+1,_lxml->cur-1,_lxml) < 0) + { + return(-1); + } + c = _xml_fgetc(fp); + if(isspace(c)) + return(_getattributes(fp,parent,_lxml)); + else if(c == _R_CONFE) + return(0); + else if(c == '/') + return (c); + + xml_error(_lxml, + "XMLERR: Bad attribute closing for '%s'='%s'.", + attr,value); + return(-1); } else if(location == 0) - attr[count++]=c; + attr[count++] = (char) c; else if(location == 1) - value[count++]=c; + value[count++] = (char) c; }