X-Git-Url: http://ftp.carnet.hr/pub/carnet-debian/scm?a=blobdiff_plain;f=src%2Fos_xml%2Fos_xml.c;h=d736f20efb2f5fef11c387e08ccf30edce731656;hb=e81e4e82e5115bf99b6fbd9ebd486de325d67ed6;hp=c370d58999d3748a26635c188bb07188fa73ea94;hpb=301048b51990573e58a30dc4a5bb4ec285cad554;p=ossec-hids.git diff --git a/src/os_xml/os_xml.c b/src/os_xml/os_xml.c index c370d58..d736f20 100755 --- a/src/os_xml/os_xml.c +++ b/src/os_xml/os_xml.c @@ -12,52 +12,42 @@ /* 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); if(c == '\n') /* add new line */ _line++; - - return(c); -} -#define FGETC(fp) _xml_fgetc(fp) + return(c); +} -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); + _lxml->ck = NULL; + free(_lxml->ln); - memset(_lxml->err,'\0', 128); - - return; - + _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,23 +156,23 @@ 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); } } - + fclose(fp); return(0); } -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,25 +201,25 @@ 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]; - + memset(elem,'\0',XML_MAXSIZE +1); 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,13 +244,13 @@ 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) continue; } - + /* real checking */ if((location == -1) && (prevv == 0)) { @@ -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 @@ -268,23 +268,26 @@ int _ReadElem(FILE *fp, int position, int parent, OS_XML *_lxml) else 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,16 +296,19 @@ 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; location = -1; - + memset(elem,'\0',XML_MAXSIZE); memset(closedelem,'\0',XML_MAXSIZE); memset(cont,'\0',XML_MAXSIZE); - + if(parent > 0) return(0); } @@ -310,24 +316,27 @@ int _ReadElem(FILE *fp, int position, int parent, OS_XML *_lxml) { count = 0; location = 1; - } + } } - + else if((location == 2) &&(c == _R_CONFE)) { 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,37 +379,77 @@ 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 */ if(type == XML_ATTR) _lxml->ck[_lxml->cur] = 1; @@ -413,87 +462,103 @@ 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; - + char attr[XML_MAXSIZE+1]; char value[XML_MAXSIZE+1]; 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); + xml_error(_lxml, + "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,40 +580,56 @@ 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; - - _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 + + /* dead code: + * location = 0; + * c_to_match = 0; + */ + + 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; } - + xml_error(_lxml, "XMLERR: End of file while reading an attribute."); return(-1); }