From a7cb332c30b51b4e27f6e57c6b58dc2d1f73f89c Mon Sep 17 00:00:00 2001 From: Darren Salt Date: Thu, 19 Apr 2007 17:24:08 +0100 Subject: Relaxed XML parsing (ABI addition). Copes with missing close tags. Copes with extra close tags iff they don't match so-far-unclosed elements. Doesn't cope with missing "/>" - that needs more info from the caller. --- src/xine-utils/xmlparser.c | 65 +++++++++++++++++++++++++++++++++++++++------- src/xine-utils/xmlparser.h | 1 + 2 files changed, 57 insertions(+), 9 deletions(-) diff --git a/src/xine-utils/xmlparser.c b/src/xine-utils/xmlparser.c index 47096705a..82e1f0ecd 100644 --- a/src/xine-utils/xmlparser.c +++ b/src/xine-utils/xmlparser.c @@ -156,7 +156,8 @@ void xml_parser_free_tree(xml_node_t *current_node) { #define STATE_NODE 1 #define STATE_COMMENT 7 -static int xml_parser_get_node (xml_node_t *current_node, char *root_name, int rec) { +static int xml_parser_get_node_internal (xml_node_t *current_node, char *root_names[], int rec, int relaxed) +{ char tok[TOKEN_SIZE]; char property_name[TOKEN_SIZE]; char node_name[TOKEN_SIZE]; @@ -164,6 +165,7 @@ static int xml_parser_get_node (xml_node_t *current_node, char *root_name, int r int res = 0; int parse_res; int bypass_get_token = 0; + int retval = 0; /* used when state==4; non-0 if there are missing */ xml_node_t *subtree = NULL; xml_node_t *current_subtree = NULL; xml_property_t *current_property = NULL; @@ -183,7 +185,7 @@ static int xml_parser_get_node (xml_node_t *current_node, char *root_name, int r /* do nothing */ break; case (T_EOF): - return 0; /* normal end */ + return retval; /* normal end */ break; case (T_M_START_1): state = STATE_NODE; @@ -252,7 +254,12 @@ static int xml_parser_get_node (xml_node_t *current_node, char *root_name, int r /* set node propertys */ subtree->props = properties; lprintf("info: rec %d new subtree %s\n", rec, node_name); - parse_res = xml_parser_get_node(subtree, node_name, rec + 1); + root_names[rec + 1] = node_name; + parse_res = xml_parser_get_node_internal(subtree, root_names, rec + 1, relaxed); + if (parse_res < -1) { + /* badly-formed XML (missing close tag) */ + return parse_res + 1 + (parse_res == -2); + } if (parse_res != 0) { return parse_res; } @@ -310,10 +317,26 @@ static int xml_parser_get_node (xml_node_t *current_node, char *root_name, int r if (xml_parser_mode == XML_PARSER_CASE_INSENSITIVE) { strtoupper(tok); } - if (strcmp(tok, root_name) == 0) { + if (strcmp(tok, root_names[rec]) == 0) { state = 4; - } else { - lprintf("error: xml struct, tok=%s, waited_tok=%s\n", tok, root_name); + } else if (relaxed) { + int r = rec; + while (--r >= 0) + if (strcmp(tok, root_names[r]) == 0) { + lprintf("warning: wanted %s, got %s - assuming missing close tags\n", root_names[rec], tok); + retval = r - rec - 1; /* -1 - (no. of implied close tags) */ + state = 4; + break; + } + /* relaxed parsing, ignoring extra close tag (but we don't handle out-of-order) */ + if (r < 0) { + lprintf("warning: extra close tag %s - ignoring\n", tok); + state = 10; + } + } + else + { + lprintf("error: xml struct, tok=%s, waited_tok=%s\n", tok, root_names[rec]); return -1; } break; @@ -328,7 +351,7 @@ static int xml_parser_get_node (xml_node_t *current_node, char *root_name, int r case 4: switch (res) { case (T_M_STOP_1): - return 0; + return retval; break; default: lprintf("error: unexpected token \"%s\", state %d\n", tok, state); @@ -435,6 +458,19 @@ static int xml_parser_get_node (xml_node_t *current_node, char *root_name, int r state = 9; break; } + break; + + /* > expected (following unmatched "child) && (!tmp_node->child->next)) { *root_node = tmp_node->child; free_xml_node(tmp_node); @@ -471,6 +514,10 @@ int xml_parser_build_tree(xml_node_t **root_node) { return res; } +int xml_parser_build_tree(xml_node_t **root_node) { + return xml_parser_build_tree_relaxed (root_node, 0); +} + const char *xml_parser_get_property (const xml_node_t *node, const char *name) { xml_property_t *prop; diff --git a/src/xine-utils/xmlparser.h b/src/xine-utils/xmlparser.h index f202ca28d..8d4915abf 100644 --- a/src/xine-utils/xmlparser.h +++ b/src/xine-utils/xmlparser.h @@ -57,6 +57,7 @@ typedef struct xml_node_s { void xml_parser_init(const char * buf, int size, int mode) XINE_PROTECTED; int xml_parser_build_tree(xml_node_t **root_node) XINE_PROTECTED; +int xml_parser_build_tree_relaxed(xml_node_t **root_node, int relaxed) XINE_PROTECTED; void xml_parser_free_tree(xml_node_t *root_node) XINE_PROTECTED; -- cgit v1.2.3 From b9369613bf1c5aababf2a40a96e2f85b0510ebe4 Mon Sep 17 00:00:00 2001 From: Darren Salt Date: Sat, 21 Apr 2007 23:09:24 +0100 Subject: Use an enumeration for XML lexer state tracking. --- src/xine-utils/xmllexer.c | 82 +++++++++++++++++++++++++++++------------------ 1 file changed, 50 insertions(+), 32 deletions(-) diff --git a/src/xine-utils/xmllexer.c b/src/xine-utils/xmllexer.c index 754a006f9..4198b197b 100644 --- a/src/xine-utils/xmllexer.c +++ b/src/xine-utils/xmllexer.c @@ -61,9 +61,27 @@ void lexer_init(const char * buf, int size) { lprintf("buffer length %d\n", size); } +typedef enum { + STATE_UNKNOWN = -1, + STATE_IDLE, + STATE_EOL, + STATE_SEPAR, + STATE_T_M_START, + STATE_T_M_STOP_1, + STATE_T_M_STOP_2, + STATE_T_EQUAL, + STATE_T_STRING_SINGLE, + STATE_T_STRING_DOUBLE, + STATE_T_COMMENT, + STATE_T_TI_STOP, + STATE_T_DASHDASH, + STATE_T_C_STOP, + STATE_IDENT /* must be last */ +} lexer_state_t; + int lexer_get_token(char * tok, int tok_size) { int tok_pos = 0; - int state = 0; + lexer_state_t state = STATE_IDLE; char c; if (tok) { @@ -75,69 +93,69 @@ int lexer_get_token(char * tok, int tok_size) { /* normal mode */ switch (state) { /* init state */ - case 0: + case STATE_IDLE: switch (c) { case '\n': case '\r': - state = 1; + state = STATE_EOL; tok[tok_pos] = c; tok_pos++; break; case ' ': case '\t': - state = 2; + state = STATE_SEPAR; tok[tok_pos] = c; tok_pos++; break; case '<': - state = 3; + state = STATE_T_M_START; tok[tok_pos] = c; tok_pos++; break; case '>': - state = 4; + state = STATE_T_M_STOP_1; tok[tok_pos] = c; tok_pos++; break; case '/': if (!in_comment) - state = 5; + state = STATE_T_M_STOP_2; tok[tok_pos] = c; tok_pos++; break; case '=': - state = 6; + state = STATE_T_EQUAL; tok[tok_pos] = c; tok_pos++; break; case '\"': /* " */ - state = 7; + state = STATE_T_STRING_DOUBLE; break; case '\'': /* " */ - state = 12; + state = STATE_T_STRING_SINGLE; break; case '-': - state = 10; + state = STATE_T_DASHDASH; tok[tok_pos] = c; tok_pos++; break; case '?': - state = 9; + state = STATE_T_TI_STOP; tok[tok_pos] = c; tok_pos++; break; default: - state = 100; + state = STATE_IDENT; tok[tok_pos] = c; tok_pos++; break; @@ -146,7 +164,7 @@ int lexer_get_token(char * tok, int tok_size) { break; /* end of line */ - case 1: + case STATE_EOL: if (c == '\n' || (c == '\r')) { tok[tok_pos] = c; lexbuf_pos++; @@ -158,7 +176,7 @@ int lexer_get_token(char * tok, int tok_size) { break; /* T_SEPAR */ - case 2: + case STATE_SEPAR: if (c == ' ' || (c == '\t')) { tok[tok_pos] = c; lexbuf_pos++; @@ -170,7 +188,7 @@ int lexer_get_token(char * tok, int tok_size) { break; /* T_M_START < or ') { tok[tok_pos] = c; lexbuf_pos++; @@ -223,13 +241,13 @@ int lexer_get_token(char * tok, int tok_size) { break; /* T_EQUAL */ - case 6: + case STATE_T_EQUAL: tok[tok_pos] = '\0'; return T_EQUAL; break; /* T_STRING */ - case 7: + case STATE_T_STRING_DOUBLE: tok[tok_pos] = c; lexbuf_pos++; if (c == '\"') { /* " */ @@ -240,7 +258,7 @@ int lexer_get_token(char * tok, int tok_size) { break; /* T_C_START or T_DOCTYPE_START */ - case 8: + case STATE_T_COMMENT: switch (c) { case '-': lexbuf_pos++; @@ -271,7 +289,7 @@ int lexer_get_token(char * tok, int tok_size) { break; /* T_TI_STOP */ - case 9: + case STATE_T_TI_STOP: if (c == '>') { tok[tok_pos] = c; lexbuf_pos++; @@ -285,24 +303,24 @@ int lexer_get_token(char * tok, int tok_size) { break; /* -- */ - case 10: + case STATE_T_DASHDASH: switch (c) { case '-': tok[tok_pos] = c; tok_pos++; lexbuf_pos++; - state = 11; + state = STATE_T_C_STOP; break; default: tok[tok_pos] = c; tok_pos++; lexbuf_pos++; - state = 100; + state = STATE_IDENT; } break; /* --> */ - case 11: + case STATE_T_C_STOP: switch (c) { case '>': tok[tok_pos] = c; @@ -322,12 +340,12 @@ int lexer_get_token(char * tok, int tok_size) { tok[tok_pos] = c; tok_pos++; lexbuf_pos++; - state = 100; + state = STATE_IDENT; } break; /* T_STRING (single quotes) */ - case 12: + case STATE_T_STRING_SINGLE: tok[tok_pos] = c; lexbuf_pos++; if (c == '\'') { /* " */ @@ -338,7 +356,7 @@ int lexer_get_token(char * tok, int tok_size) { break; /* IDENT */ - case 100: + case STATE_IDENT: switch (c) { case '<': case '>': @@ -355,13 +373,13 @@ int lexer_get_token(char * tok, int tok_size) { tok[tok_pos] = c; tok_pos++; lexbuf_pos++; - state = 9; + state = STATE_T_TI_STOP; break; case '-': tok[tok_pos] = c; tok_pos++; lexbuf_pos++; - state = 10; + state = STATE_T_DASHDASH; break; default: tok[tok_pos] = c; -- cgit v1.2.3 From 5fb4b3b17479cba362568cc5ec99442f92f3d819 Mon Sep 17 00:00:00 2001 From: Darren Salt Date: Sat, 21 Apr 2007 23:10:53 +0100 Subject: Use an enumeration for XML parser state tracking. --- src/xine-utils/xmlparser.c | 58 ++++++++++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 22 deletions(-) diff --git a/src/xine-utils/xmlparser.c b/src/xine-utils/xmlparser.c index 363c6381f..f48fe696c 100644 --- a/src/xine-utils/xmlparser.c +++ b/src/xine-utils/xmlparser.c @@ -152,15 +152,30 @@ void xml_parser_free_tree(xml_node_t *current_node) { xml_parser_free_tree_rec(current_node, 1); } -#define STATE_IDLE 0 -#define STATE_NODE 1 -#define STATE_COMMENT 7 +typedef enum { + /*0*/ + STATE_IDLE, + /* */ + STATE_NODE, + STATE_ATTRIBUTE, + STATE_NODE_CLOSE, + STATE_TAG_TERM, + STATE_ATTRIBUTE_EQUALS, + STATE_STRING, + /* */ + STATE_Q_NODE, + /* Others */ + STATE_COMMENT, + STATE_DOCTYPE, +} parser_state_t; + +#define Q_STATE(CURRENT,NEW) (STATE_##NEW + state - STATE_##CURRENT) static int xml_parser_get_node (xml_node_t *current_node, char *root_name, int rec) { char tok[TOKEN_SIZE]; char property_name[TOKEN_SIZE]; char node_name[TOKEN_SIZE]; - int state = STATE_IDLE; + parser_state_t state = STATE_IDLE; int res = 0; int parse_res; int bypass_get_token = 0; @@ -189,16 +204,16 @@ static int xml_parser_get_node (xml_node_t *current_node, char *root_name, int r state = STATE_NODE; break; case (T_M_START_2): - state = 3; + state = STATE_NODE_CLOSE; break; case (T_C_START): state = STATE_COMMENT; break; case (T_TI_START): - state = 8; + state = STATE_Q_NODE; break; case (T_DOCTYPE_START): - state = 9; + state = STATE_DOCTYPE; break; case (T_DATA): /* current data */ @@ -236,7 +251,8 @@ static int xml_parser_get_node (xml_node_t *current_node, char *root_name, int r break; } break; - case 2: + + case STATE_ATTRIBUTE: switch (res) { case (T_EOL): case (T_SEPAR): @@ -293,7 +309,7 @@ static int xml_parser_get_node (xml_node_t *current_node, char *root_name, int r strtoupper(tok); } strcpy(property_name, tok); - state = 5; + state = STATE_ATTRIBUTE_EQUALS; lprintf("info: current property name \"%s\"\n", property_name); break; default: @@ -303,7 +319,7 @@ static int xml_parser_get_node (xml_node_t *current_node, char *root_name, int r } break; - case 3: + case STATE_NODE_CLOSE: switch (res) { case (T_IDENT): /* must be equal to root_name */ @@ -311,7 +327,7 @@ static int xml_parser_get_node (xml_node_t *current_node, char *root_name, int r strtoupper(tok); } if (strcmp(tok, root_name) == 0) { - state = 4; + state = STATE_TAG_TERM; } else { lprintf("error: xml struct, tok=%s, waited_tok=%s\n", tok, root_name); return -1; @@ -325,7 +341,7 @@ static int xml_parser_get_node (xml_node_t *current_node, char *root_name, int r break; /* > expected */ - case 4: + case STATE_TAG_TERM: switch (res) { case (T_M_STOP_1): return 0; @@ -338,18 +354,18 @@ static int xml_parser_get_node (xml_node_t *current_node, char *root_name, int r break; /* = or > or ident or separator expected */ - case 5: + case STATE_ATTRIBUTE_EQUALS: switch (res) { case (T_EOL): case (T_SEPAR): /* do nothing */ break; case (T_EQUAL): - state = 6; + state = STATE_STRING; break; case (T_IDENT): bypass_get_token = 1; /* jump to state 2 without get a new token */ - state = 2; + state = STATE_ATTRIBUTE; break; case (T_M_STOP_1): /* add a new property without value */ @@ -363,7 +379,7 @@ static int xml_parser_get_node (xml_node_t *current_node, char *root_name, int r current_property->name = strdup (property_name); lprintf("info: new property %s\n", current_property->name); bypass_get_token = 1; /* jump to state 2 without get a new token */ - state = 2; + state = STATE_ATTRIBUTE; break; default: lprintf("error: unexpected token \"%s\", state %d\n", tok, state); @@ -373,7 +389,7 @@ static int xml_parser_get_node (xml_node_t *current_node, char *root_name, int r break; /* string or ident or separator expected */ - case 6: + case STATE_STRING: switch (res) { case (T_EOL): case (T_SEPAR): @@ -392,7 +408,7 @@ static int xml_parser_get_node (xml_node_t *current_node, char *root_name, int r current_property->name = strdup(property_name); current_property->value = lexer_decode_entities(tok); lprintf("info: new property %s=%s\n", current_property->name, current_property->value); - state = 2; + state = STATE_ATTRIBUTE; break; default: lprintf("error: unexpected token \"%s\", state %d\n", tok, state); @@ -414,25 +430,23 @@ static int xml_parser_get_node (xml_node_t *current_node, char *root_name, int r break; /* ?> expected */ - case 8: + case STATE_Q_NODE: switch (res) { case (T_TI_STOP): state = 0; break; default: - state = 8; break; } break; /* > expected */ - case 9: + case STATE_DOCTYPE: switch (res) { case (T_M_STOP_1): state = 0; break; default: - state = 9; break; } break; -- cgit v1.2.3 From 497d74fe5b6a68b904a6944a9c60dd3c631654a6 Mon Sep 17 00:00:00 2001 From: Darren Salt Date: Sat, 21 Apr 2007 23:36:18 +0100 Subject: Stop ignoring elements, and parse them for attributes. In the XML data structure returned by xml_parser_build_tree(), the primary content is the directly-returned node, and the extra elements follow this (use ->next) though they appear first in the XML text, thus maintaining backward compatibility. --- ChangeLog | 3 ++ src/xine-utils/xmllexer.c | 5 ++- src/xine-utils/xmlparser.c | 109 ++++++++++++++++++++++++++++++++++++--------- 3 files changed, 96 insertions(+), 21 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1f3dce98c..8d0413b2d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,9 @@ xine-lib (1.1.7) (unreleased) * Support libdca (new name for libdts) by shuffling around the dts.h file. * Add support for MDHD version 1 atom in demux_qt. [bug #1679398] * Handle single-quoted attribute values in XML. + * The XML parser no longer ignores elements. + Such elements are handled as if they were after the XML content for + compatibility reasons, though they must appear before it. xine-lib (1.1.6) * Split the DirectFB plugin into X11 and non-X versions. diff --git a/src/xine-utils/xmllexer.c b/src/xine-utils/xmllexer.c index 4198b197b..028a41673 100644 --- a/src/xine-utils/xmllexer.c +++ b/src/xine-utils/xmllexer.c @@ -149,7 +149,8 @@ int lexer_get_token(char * tok, int tok_size) { break; case '?': - state = STATE_T_TI_STOP; + if (!in_comment) + state = STATE_T_TI_STOP; tok[tok_pos] = c; tok_pos++; break; @@ -295,6 +296,8 @@ int lexer_get_token(char * tok, int tok_size) { lexbuf_pos++; tok_pos++; /* FIXME */ tok[tok_pos] = '\0'; + if (!in_comment) + lex_mode = DATA; return T_TI_STOP; } else { tok[tok_pos] = '\0'; diff --git a/src/xine-utils/xmlparser.c b/src/xine-utils/xmlparser.c index f48fe696c..c8723a12e 100644 --- a/src/xine-utils/xmlparser.c +++ b/src/xine-utils/xmlparser.c @@ -164,6 +164,11 @@ typedef enum { STATE_STRING, /* */ STATE_Q_NODE, + STATE_Q_ATTRIBUTE, + STATE_Q_NODE_CLOSE, + STATE_Q_TAG_TERM, + STATE_Q_ATTRIBUTE_EQUALS, + STATE_Q_STRING, /* Others */ STATE_COMMENT, STATE_DOCTYPE, @@ -232,6 +237,7 @@ static int xml_parser_get_node (xml_node_t *current_node, char *root_name, int r break; case STATE_NODE: + case STATE_Q_NODE: switch (res) { case (T_IDENT): properties = NULL; @@ -241,8 +247,13 @@ static int xml_parser_get_node (xml_node_t *current_node, char *root_name, int r if (xml_parser_mode == XML_PARSER_CASE_INSENSITIVE) { strtoupper(tok); } - strcpy(node_name, tok); - state = 2; + if (state == STATE_Q_NODE) { + snprintf (node_name, TOKEN_SIZE, "?%s", tok); + state = STATE_Q_ATTRIBUTE; + } else { + strcpy(node_name, tok); + state = STATE_ATTRIBUTE; + } lprintf("info: current node name \"%s\"\n", node_name); break; default: @@ -284,6 +295,7 @@ static int xml_parser_get_node (xml_node_t *current_node, char *root_name, int r case (T_M_STOP_2): /* new leaf */ /* new subtree */ + new_leaf: subtree = new_xml_node(); /* set node name */ @@ -305,11 +317,12 @@ static int xml_parser_get_node (xml_node_t *current_node, char *root_name, int r break; case (T_IDENT): /* save property name */ + new_prop: if (xml_parser_mode == XML_PARSER_CASE_INSENSITIVE) { strtoupper(tok); } strcpy(property_name, tok); - state = STATE_ATTRIBUTE_EQUALS; + state = Q_STATE(ATTRIBUTE, ATTRIBUTE_EQUALS); lprintf("info: current property name \"%s\"\n", property_name); break; default: @@ -319,6 +332,23 @@ static int xml_parser_get_node (xml_node_t *current_node, char *root_name, int r } break; + case STATE_Q_ATTRIBUTE: + switch (res) { + case (T_EOL): + case (T_SEPAR): + /* nothing */ + break; + case (T_TI_STOP): + goto new_leaf; + case (T_IDENT): + goto new_prop; + default: + lprintf("error: unexpected token \"%s\", state %d\n", tok, state); + return -1; + break; + } + break; + case STATE_NODE_CLOSE: switch (res) { case (T_IDENT): @@ -386,10 +416,46 @@ static int xml_parser_get_node (xml_node_t *current_node, char *root_name, int r return -1; break; } + break; + + /* = or ?> or ident or separator expected */ + case STATE_Q_ATTRIBUTE_EQUALS: + switch (res) { + case (T_EOL): + case (T_SEPAR): + /* do nothing */ + break; + case (T_EQUAL): + state = STATE_Q_STRING; + break; + case (T_IDENT): + bypass_get_token = 1; /* jump to state 2 without get a new token */ + state = STATE_Q_ATTRIBUTE; + break; + case (T_TI_STOP): + /* add a new property without value */ + if (current_property == NULL) { + properties = new_xml_property(); + current_property = properties; + } else { + current_property->next = new_xml_property(); + current_property = current_property->next; + } + current_property->name = strdup (property_name); + lprintf("info: new property %s\n", current_property->name); + bypass_get_token = 1; /* jump to state 2 without get a new token */ + state = STATE_Q_ATTRIBUTE; + break; + default: + lprintf("error: unexpected token \"%s\", state %d\n", tok, state); + return -1; + break; + } break; /* string or ident or separator expected */ case STATE_STRING: + case STATE_Q_STRING: switch (res) { case (T_EOL): case (T_SEPAR): @@ -408,7 +474,7 @@ static int xml_parser_get_node (xml_node_t *current_node, char *root_name, int r current_property->name = strdup(property_name); current_property->value = lexer_decode_entities(tok); lprintf("info: new property %s=%s\n", current_property->name, current_property->value); - state = STATE_ATTRIBUTE; + state = Q_STATE(STRING, ATTRIBUTE); break; default: lprintf("error: unexpected token \"%s\", state %d\n", tok, state); @@ -423,18 +489,6 @@ static int xml_parser_get_node (xml_node_t *current_node, char *root_name, int r case (T_C_STOP): state = STATE_IDLE; break; - default: - state = STATE_COMMENT; - break; - } - break; - - /* ?> expected */ - case STATE_Q_NODE: - switch (res) { - case (T_TI_STOP): - state = 0; - break; default: break; } @@ -468,13 +522,25 @@ static int xml_parser_get_node (xml_node_t *current_node, char *root_name, int r } int xml_parser_build_tree(xml_node_t **root_node) { - xml_node_t *tmp_node; + xml_node_t *tmp_node, *pri_node, *q_node = NULL; int res; tmp_node = new_xml_node(); res = xml_parser_get_node(tmp_node, "", 0); - if ((tmp_node->child) && (!tmp_node->child->next)) { - *root_node = tmp_node->child; + + /* find first non- node */; + for (pri_node = tmp_node->child; + pri_node && pri_node->name[0] == '?'; + pri_node = pri_node->next) + q_node = pri_node; /* last node (eventually), or NULL */ + + if (pri_node && !pri_node->next) { + /* move the tail to the head (for compatibility reasons) */ + if (q_node) { + pri_node->next = tmp_node->child; + q_node->next = NULL; + } + *root_node = pri_node; free_xml_node(tmp_node); res = 0; } else { @@ -603,5 +669,8 @@ static void xml_parser_dump_node (const xml_node_t *node, int indent) { } void xml_parser_dump_tree (const xml_node_t *node) { - xml_parser_dump_node (node, 0); + do { + xml_parser_dump_node (node, 0); + node = node->next; + } while (node); } -- cgit v1.2.3 From 559008cadf0bc3457696e145b0abe764132fe92d Mon Sep 17 00:00:00 2001 From: Darren Salt Date: Sun, 22 Apr 2007 00:13:46 +0100 Subject: Don't drop elements with missing close tags. --- src/xine-utils/xmlparser.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/xine-utils/xmlparser.c b/src/xine-utils/xmlparser.c index 82e1f0ecd..7140bea5d 100644 --- a/src/xine-utils/xmlparser.c +++ b/src/xine-utils/xmlparser.c @@ -256,11 +256,7 @@ static int xml_parser_get_node_internal (xml_node_t *current_node, char *root_na lprintf("info: rec %d new subtree %s\n", rec, node_name); root_names[rec + 1] = node_name; parse_res = xml_parser_get_node_internal(subtree, root_names, rec + 1, relaxed); - if (parse_res < -1) { - /* badly-formed XML (missing close tag) */ - return parse_res + 1 + (parse_res == -2); - } - if (parse_res != 0) { + if (parse_res == -1 || parse_res > 0) { return parse_res; } if (current_subtree == NULL) { @@ -270,6 +266,10 @@ static int xml_parser_get_node_internal (xml_node_t *current_node, char *root_na current_subtree->next = subtree; current_subtree = subtree; } + if (parse_res < -1) { + /* badly-formed XML (missing close tag) */ + return parse_res + 1 + (parse_res == -2); + } state = STATE_IDLE; break; case (T_M_STOP_2): -- cgit v1.2.3 From 0ba64cf66fef7411ae2626027c7dfa4a00d4f432 Mon Sep 17 00:00:00 2001 From: Darren Salt Date: Mon, 23 Apr 2007 23:49:00 +0100 Subject: Kill a "may be used uninitialised" warning. --- src/xine-utils/xmlparser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xine-utils/xmlparser.c b/src/xine-utils/xmlparser.c index 93217637d..a63ac39d6 100644 --- a/src/xine-utils/xmlparser.c +++ b/src/xine-utils/xmlparser.c @@ -566,7 +566,7 @@ static int xml_parser_get_node (xml_node_t *current_node, int relaxed) } int xml_parser_build_tree_relaxed(xml_node_t **root_node, int relaxed) { - xml_node_t *tmp_node, *pri_node, *q_node; + xml_node_t *tmp_node, *pri_node, *q_node = NULL; int res; tmp_node = new_xml_node(); -- cgit v1.2.3