X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fpalacios%2Fvmm_xml.c;h=a9c66592501e611773dbc59cb796c43deaebf43c;hb=210c49c1f9b523ff94fd5b6791961d242d5bbae4;hp=f3641be5159ccec1e99b0dab094869a6df52b1d5;hpb=1f7a670397e97ea1028294d7b7b45d6ef1797d65;p=palacios.git diff --git a/palacios/src/palacios/vmm_xml.c b/palacios/src/palacios/vmm_xml.c index f3641be..a9c6659 100644 --- a/palacios/src/palacios/vmm_xml.c +++ b/palacios/src/palacios/vmm_xml.c @@ -41,6 +41,8 @@ #define V3_XML_DUP 0x20 // attribute name and value are strduped // +static char * V3_XML_NIL[] = { NULL }; // empty, null terminated array of strings + #define V3_XML_WS "\t\r\n " // whitespace #define V3_XML_ERRL 128 // maximum error string length @@ -51,38 +53,35 @@ struct v3_xml_root { // additional data for the root tag char *str_ptr; // original xml string char *tmp_start; // start of work area char *tmp_end; // end of work area - char **ent; // general entities (ampersand sequences) - char ***attr; // default attributes short standalone; // non-zero if - char err[V3_XML_ERRL]; // error string }; static char * empty_attrib_list[] = { NULL }; // empty, null terminated array of strings -static void * tmp_realloc(void * old_ptr, uint_t old_size, uint_t new_size) { - void * new_buf = V3_Malloc(new_size); +static void * tmp_realloc(void * old_ptr, size_t old_size, size_t new_size) { + void * new_buf = NULL; + + new_buf = V3_Malloc(new_size); + if (new_buf == NULL) { + PrintError(VM_NONE, VCORE_NONE, "Cannot allocate in tmp_realloc in xml\n"); return NULL; } + memset(new_buf, 0, new_size); + memcpy(new_buf, old_ptr, old_size); V3_Free(old_ptr); return new_buf; } - - - - // set an error string and return root -static void v3_xml_err(struct v3_xml_root * root, char * xml_str, const char * err, ...) { - va_list ap; +static void v3_xml_err(struct v3_xml_root * root, char * xml_str, const char * err, const char *arg) { int line = 1; char * tmp; - char fmt[V3_XML_ERRL]; for (tmp = root->tmp_start; tmp < xml_str; tmp++) { if (*tmp == '\n') { @@ -90,14 +89,8 @@ static void v3_xml_err(struct v3_xml_root * root, char * xml_str, const char * e } } - snprintf(fmt, V3_XML_ERRL, "[error near line %d]: %s", line, err); - - va_start(ap, err); - vsnprintf(root->err, V3_XML_ERRL, fmt, ap); - va_end(ap); - - PrintError("XML Error: %s\n", root->err); - + PrintError(VM_NONE, VCORE_NONE, "XML Error: [error near line %d]: %s (%s)", line, err ,arg ? arg : ""); + // free memory v3_xml_free(&(root->xml)); @@ -134,8 +127,6 @@ struct v3_xml * v3_xml_idx(struct v3_xml * xml, int idx) { // returns the value of the requested tag attribute or NULL if not found const char * v3_xml_attr(struct v3_xml * xml, const char * attr) { int i = 0; - int j = 1; - struct v3_xml_root * root = (struct v3_xml_root *)xml; if ((!xml) || (!xml->attr)) { return NULL; @@ -149,59 +140,18 @@ const char * v3_xml_attr(struct v3_xml * xml, const char * attr) { return xml->attr[i + 1]; // found attribute } - while (root->xml.parent != NULL) { - root = (struct v3_xml_root *)root->xml.parent; // root tag - } - - for (i = 0; - ( (root->attr[i] != NULL) && - (strcasecmp(xml->name, root->attr[i][0]) != 0) ); - i++); - - if (! root->attr[i]) { - return NULL; // no matching default attributes - } - - while ((root->attr[i][j] != NULL) && (strcasecmp(attr, root->attr[i][j]) != 0)) { - j += 3; - } - - return (root->attr[i][j] != NULL) ? root->attr[i][j + 1] : NULL; // found default + return NULL; // found default } -// same as v3_xml_get but takes an already initialized va_list -static struct v3_xml * v3_xml_vget(struct v3_xml * xml, va_list ap) { - char * name = va_arg(ap, char *); - int idx = -1; - if ((name != NULL) && (*name != 0)) { - idx = va_arg(ap, int); - xml = v3_xml_child(xml, name); - } - return (idx < 0) ? xml : v3_xml_vget(v3_xml_idx(xml, idx), ap); -} - -// Traverses the xml tree to retrieve a specific subtag. Takes a variable -// length list of tag names and indexes. The argument list must be terminated -// by either an index of -1 or an empty string tag name. Example: -// title = v3_xml_get(library, "shelf", 0, "book", 2, "title", -1); -// This retrieves the title of the 3rd book on the 1st shelf of library. -// Returns NULL if not found. -struct v3_xml * v3_xml_get(struct v3_xml * xml, ...) { - va_list ap; - struct v3_xml * r; - - va_start(ap, xml); - r = v3_xml_vget(xml, ap); - va_end(ap); - return r; -} // sets a flag for the given tag and returns the tag static struct v3_xml * v3_xml_set_flag(struct v3_xml * xml, short flag) { - if (xml) xml->flags |= flag; + if (xml) { + xml->flags |= flag; + } return xml; } @@ -215,11 +165,10 @@ static struct v3_xml * v3_xml_set_flag(struct v3_xml * xml, short flag) // for cdata sections, ' ' for attribute normalization, or '*' for non-cdata // attribute normalization. Returns s, or if the decoded string is longer than // s, returns a malloced string that must be freed. -static char * v3_xml_decode(char * s, char ** ent, char t) { +static char * v3_xml_decode(char * s, char t) { char * e; char * r = s; - char * m = s; - long b, c, d, l; + long c, l; // normalize line endings for (; *s; s++) { @@ -262,28 +211,6 @@ static char * v3_xml_decode(char * s, char ** ent, char t) { *(s++) = c; memmove(s, strchr(s, ';') + 1, strlen(strchr(s, ';'))); - } else if ( ( (*s == '&') && - ((t == '&') || (t == ' ') || (t == '*'))) || - ( (*s == '%') && (t == '%'))) { - // entity reference` - - for ( (b = 0); - (ent[b]) && (strncmp(s + 1, ent[b], strlen(ent[b])) != 0); - (b += 2)); // find entity in entity list - - if (ent[b++]) { // found a match - if (((c = strlen(ent[b])) - 1) > ((e = strchr(s, ';')) - s)) { - l = (d = (s - r)) + c + strlen(e); // new length - r = ((r == m) ? strcpy(V3_Malloc(l), r) : tmp_realloc(r, strlen(r), l)); - e = strchr((s = r + d), ';'); // fix up pointers - } - - memmove(s + c, e + 1, strlen(e)); // shift rest of string - strncpy(s, ent[b], c); // copy in replacement text - } else { - // not a known entity - s++; - } } else if ( ( (t == ' ') || (t == '*')) && (isspace(*s))) { *(s++) = ' '; @@ -327,16 +254,29 @@ static void v3_xml_char_content(struct v3_xml_root * root, char * s, size_t len, } s[len] = '\0'; // null terminate text (calling functions anticipate this) - len = strlen(s = v3_xml_decode(s, root->ent, t)) + 1; + len = strlen(s = v3_xml_decode(s, t)) + 1; - if (! *(xml->txt)) { + if (xml->txt[0] == '\0') { // empty string // initial character content xml->txt = s; } else { + // allocate our own memory and make a copy - xml->txt = (xml->flags & V3_XML_TXTM) ? - (tmp_realloc(xml->txt, strlen(xml->txt), (l = strlen(xml->txt)) + len)) : - (strcpy(V3_Malloc((l = strlen(xml->txt)) + len), xml->txt)); + if (xml->flags & V3_XML_TXTM) { + xml->txt = (tmp_realloc(xml->txt, strlen(xml->txt), (l = strlen(xml->txt)) + len)); + } else { + char * tmp = NULL; + + tmp = V3_Malloc((l = strlen(xml->txt)) + len); + + if (!tmp) { + PrintError(VM_NONE, VCORE_NONE, "Cannot allocate in xml char content\n"); + return ; + } + + strcpy(tmp, xml->txt); + xml->txt = tmp; + } strcpy(xml->txt + l, s); // add new char content @@ -355,7 +295,7 @@ static int v3_xml_close_tag(struct v3_xml_root * root, char * name, char * s) { if ( (root->cur == NULL) || (root->cur->name == NULL) || (strcasecmp(name, root->cur->name))) { - v3_xml_err(root, s, "unexpected closing tag ", name); + v3_xml_err(root, s, "unexpected closing tag", name); return -1; } @@ -363,37 +303,6 @@ static int v3_xml_close_tag(struct v3_xml_root * root, char * name, char * s) { return 0; } -#if 0 -// checks for circular entity references, returns non-zero if no circular -// references are found, zero otherwise -static int v3_xml_ent_ok(char * name, char * s, char ** ent) { - int i; - - for (; ; s++) { - while ((*s != '\0') && (*s != '&')) { - // find next entity reference - s++; - } - - if (*s == '\0') { - return 1; - } - - if (strncmp(s + 1, name, strlen(name)) == 0) { - // circular ref. - return 0; - } - - for (i = 0; (ent[i]) && (strncmp(ent[i], s + 1, strlen(ent[i]))); i += 2); - - if ((ent[i] != NULL) && (v3_xml_ent_ok(name, ent[i + 1], ent) == 0)) { - return 0; - } - } -} -#endif - - // frees a tag attribute list static void v3_xml_free_attr(char **attr) { @@ -412,16 +321,6 @@ static void v3_xml_free_attr(char **attr) { m = attr[i + 1]; // list of which names and values are malloced - for (i = 0; m[i]; i++) { - if (m[i] & V3_XML_NAMEM) { - V3_Free(attr[i * 2]); - } - - if (m[i] & V3_XML_TXTM) { - V3_Free(attr[(i * 2) + 1]); - } - } - V3_Free(m); V3_Free(attr); } @@ -433,28 +332,26 @@ static void v3_xml_free_attr(char **attr) { // returns a new empty v3_xml structure with the given root tag name static struct v3_xml * v3_xml_new(const char * name) { - static char * ent[] = { "lt;", "<", "gt;", ">", "quot;", """, - "apos;", "'", "amp;", "&", NULL }; struct v3_xml_root * root = (struct v3_xml_root *)V3_Malloc(sizeof(struct v3_xml_root)); + + if (!root) { + PrintError(VM_NONE, VCORE_NONE, "Cannot allocate in xml_new\n"); + return NULL; + } + memset(root, 0, sizeof(struct v3_xml_root)); root->xml.name = (char *)name; root->cur = &root->xml; root->xml.txt = ""; - memset(root->err, 0, V3_XML_ERRL); - root->ent = V3_Malloc(sizeof(ent)); - memcpy(root->ent, ent, sizeof(ent)); - - root->xml.attr = empty_attrib_list; - root->attr = (char ***)(empty_attrib_list); return &root->xml; } // inserts an existing tag into an v3_xml structure -static struct v3_xml * v3_xml_insert(struct v3_xml * xml, struct v3_xml * dest, size_t off) { +struct v3_xml * v3_xml_insert(struct v3_xml * xml, struct v3_xml * dest, size_t off) { struct v3_xml * cur, * prev, * head; xml->next = NULL; @@ -537,6 +434,12 @@ static struct v3_xml * v3_xml_add_child(struct v3_xml * xml, const char * name, } child = (struct v3_xml *)V3_Malloc(sizeof(struct v3_xml)); + + if (!child) { + PrintError(VM_NONE, VCORE_NONE, "Cannot allocate in xml_add_child\n"); + return NULL; + } + memset(child, 0, sizeof(struct v3_xml)); child->name = (char *)name; @@ -575,14 +478,20 @@ static struct v3_xml * parse_str(char * buf, size_t len) { char last_char; char * tag_ptr; char ** attr; - char ** tmp_attr = NULL; // initialize a to avoid compile warning int attr_idx; - int i, j; + + if (buf==NULL) { + return NULL; + } + + if (root==NULL) { + return NULL; + } root->str_ptr = buf; if (len == 0) { - v3_xml_err(root, NULL, "Empty XML String\n"); + v3_xml_err(root, NULL, "Empty XML String", 0); return NULL; } @@ -598,7 +507,7 @@ static struct v3_xml * parse_str(char * buf, size_t len) { } if (*buf == '\0') { - v3_xml_err(root, buf, "root tag missing"); + v3_xml_err(root, buf, "root tag missing", 0); return NULL; } @@ -610,7 +519,7 @@ static struct v3_xml * parse_str(char * buf, size_t len) { // new tag if (root->cur == NULL) { - v3_xml_err(root, tag_ptr, "markup outside of root element"); + v3_xml_err(root, tag_ptr, "markup outside of root element", 0); return NULL; } @@ -622,17 +531,7 @@ static struct v3_xml * parse_str(char * buf, size_t len) { *(buf++) = '\0'; } - // check if attribute follows tag - if ((*buf) && (*buf != '/') && (*buf != '>')) { - // there is an attribute - // find attributes for correct tag - for ((i = 0); - ((tmp_attr = root->attr[i]) && - (strcasecmp(tmp_attr[0], tag_ptr) != 0)); - (i++)) ; - - // 'tmp_attr' now points to the attribute list associated with 'tag_ptr' - } + // attributes are name value pairs, // 2nd to last entry is null (end of list) @@ -656,15 +555,33 @@ static struct v3_xml * parse_str(char * buf, size_t len) { (2 * sizeof(char *))), ((attr_cnt * (2 * sizeof(char *))) + (2 * sizeof(char *)))); - + + if (!attr) { + PrintError(VM_NONE, VCORE_NONE, "Cannot reallocate in xml parse string\n"); + return NULL; + } + attr[last_idx] = tmp_realloc(attr[last_idx - 2], attr_cnt, (attr_cnt + 1)); + + if (!attr[last_idx]) { + PrintError(VM_NONE, VCORE_NONE, "Cannot reallocate in xml parse string\n"); + return NULL; + } + } else { attr = V3_Malloc(4 * sizeof(char *)); + if (!attr) { + PrintError(VM_NONE, VCORE_NONE, "Cannot allocate in xml parse string\n"); + return NULL; + } attr[last_idx] = V3_Malloc(2); + if (!attr[last_idx]) { + PrintError(VM_NONE, VCORE_NONE, "Cannot alloocate in xml parse string\n"); + return NULL; + } } - attr[attr_idx] = buf; // set attribute name attr[val_idx] = ""; // temporary attribute value @@ -674,9 +591,9 @@ static struct v3_xml * parse_str(char * buf, size_t len) { buf += strcspn(buf, V3_XML_WS "=/>"); if ((*buf == '=') || isspace(*buf)) { - + *(buf++) = '\0'; // null terminate tag attribute name - + // eat whitespace (and more multiple '=' ?) buf += strspn(buf, V3_XML_WS "="); @@ -693,25 +610,14 @@ static struct v3_xml * parse_str(char * buf, size_t len) { // null terminate attribute val *(buf++) = '\0'; } else { + char err_buf[2] = {quote_char,0}; + v3_xml_free_attr(attr); - v3_xml_err(root, tag_ptr, "missing %c", quote_char); + v3_xml_err(root, tag_ptr, "missing quote char", err_buf); return NULL; } - for (j = 1; - ( (tmp_attr) && (tmp_attr[j]) && - (strcasecmp(tmp_attr[j], attr[attr_idx]) != 0)); - j += 3); - - attr[val_idx] = v3_xml_decode(attr[val_idx], root->ent, - ((tmp_attr && tmp_attr[j]) ? - *tmp_attr[j + 2] : - ' ')); - - if ( (attr[val_idx] < tag_ptr) || - (attr[val_idx] > buf) ) { - attr[last_idx][attr_cnt - 1] = V3_XML_TXTM; // value malloced - } + attr[val_idx] = v3_xml_decode(attr[val_idx], ' '); } } @@ -730,7 +636,7 @@ static struct v3_xml * parse_str(char * buf, size_t len) { if (attr_idx > 0) { v3_xml_free_attr(attr); } - v3_xml_err(root, tag_ptr, "missing >"); + v3_xml_err(root, tag_ptr, "missing >", 0); return NULL; } v3_xml_open_tag(root, tag_ptr, attr); @@ -745,7 +651,7 @@ static struct v3_xml * parse_str(char * buf, size_t len) { if (attr_idx > 0) { v3_xml_free_attr(attr); } - v3_xml_err(root, tag_ptr, "missing >"); + v3_xml_err(root, tag_ptr, "missing >", 0); return NULL; } } else if (*buf == '/') { @@ -755,7 +661,7 @@ static struct v3_xml * parse_str(char * buf, size_t len) { quote_char = *buf; if ((*buf == '\0') && (last_char != '>')) { - v3_xml_err(root, tag_ptr, "missing >"); + v3_xml_err(root, tag_ptr, "missing >", 0); return NULL; } @@ -774,7 +680,7 @@ static struct v3_xml * parse_str(char * buf, size_t len) { if ( ((buf = strstr(buf + 3, "--")) == 0) || ((*(buf += 2) != '>') && (*buf)) || ((!*buf) && (last_char != '>'))) { - v3_xml_err(root, tag_ptr, "unclosed