summaryrefslogtreecommitdiff
path: root/src/xine-utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/xine-utils')
-rw-r--r--src/xine-utils/xmllexer.c76
-rw-r--r--src/xine-utils/xmllexer.h3
-rw-r--r--src/xine-utils/xmlparser.c44
-rw-r--r--src/xine-utils/xmlparser.h14
4 files changed, 128 insertions, 9 deletions
diff --git a/src/xine-utils/xmllexer.c b/src/xine-utils/xmllexer.c
index 9a37ba29a..97a23b41e 100644
--- a/src/xine-utils/xmllexer.c
+++ b/src/xine-utils/xmllexer.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: xmllexer.c,v 1.8 2004/05/31 17:37:49 tmattern Exp $
+ * $Id: xmllexer.c,v 1.9 2005/01/16 17:51:04 dsalt Exp $
*
*/
@@ -353,11 +353,13 @@ int lexer_get_token(char * tok, int tok_size) {
}
} else {
/* data mode, stop if char equal '<' */
- if (c == '<') {
+ switch (c)
+ {
+ case '<':
tok[tok_pos] = '\0';
lex_mode = NORMAL;
return T_DATA;
- } else {
+ default:
tok[tok_pos] = c;
tok_pos++;
lexbuf_pos++;
@@ -411,3 +413,71 @@ int lexer_get_token(char * tok, int tok_size) {
lprintf("token buffer is null\n");
return T_ERROR;
}
+
+static struct {
+ char code, namelen, name[6];
+} lexer_entities[] = {
+ { '"', 4, "quot" },
+ { '&', 3, "amp" },
+ { '\'', 4, "apos" },
+ { '<', 2, "lt" },
+ { '>', 2, "gt" },
+ { 0 }
+};
+
+char *lexer_decode_entities (const char *tok)
+{
+ char *buf = xine_xmalloc (strlen (tok) + 1);
+ char *bp = buf;
+ char c;
+
+ while ((c = *tok++))
+ {
+ if (c != '&')
+ *bp++ = c;
+ else
+ {
+ /* parse the character entity (on failure, treat it as literal text) */
+ const char *tp = tok;
+ long i;
+
+ for (i = 0; lexer_entities[i].code; ++i)
+ if (!strncmp (lexer_entities[i].name, tok, lexer_entities[i].namelen)
+ && tok[lexer_entities[i].namelen] == ';')
+ break;
+ if (lexer_entities[i].code)
+ {
+ tok += lexer_entities[i].namelen + 1;
+ *bp++ = lexer_entities[i].code;
+ continue;
+ }
+
+ if (*tp++ != '#')
+ {
+ /* not a recognised name and not numeric */
+ *bp++ = '&';
+ continue;
+ }
+
+ /* entity is a number
+ * (note: strtol() allows "0x" prefix for hexadecimal, but we don't)
+ */
+ if (*tp == 'x' && tp[1] && tp[2] != 'x')
+ i = strtol (tp + 1, &tp, 16);
+ else
+ i = strtol (tp, &tp, 10);
+
+ if (i < 1 || i > 255 || *tp != ';')
+ {
+ /* out of range, or format error */
+ *bp++ = '&';
+ continue;
+ }
+
+ tok = tp + 1;
+ *bp++ = i;
+ }
+ }
+ *bp = 0;
+ return buf;
+}
diff --git a/src/xine-utils/xmllexer.h b/src/xine-utils/xmllexer.h
index 414021aad..d142c3d0f 100644
--- a/src/xine-utils/xmllexer.h
+++ b/src/xine-utils/xmllexer.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: xmllexer.h,v 1.3 2003/12/09 00:02:39 f1rmb Exp $
+ * $Id: xmllexer.h,v 1.4 2005/01/16 17:51:04 dsalt Exp $
*
*/
@@ -50,5 +50,6 @@
/* public functions */
void lexer_init(char * buf, int size);
int lexer_get_token(char * tok, int tok_size);
+char *lexer_decode_entities (const char *tok);
#endif
diff --git a/src/xine-utils/xmlparser.c b/src/xine-utils/xmlparser.c
index c36cb849b..95f9642f5 100644
--- a/src/xine-utils/xmlparser.c
+++ b/src/xine-utils/xmlparser.c
@@ -18,7 +18,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: xmlparser.c,v 1.13 2003/12/06 18:11:53 mroi Exp $
+ * $Id: xmlparser.c,v 1.14 2005/01/16 17:51:04 dsalt Exp $
*
*/
@@ -205,7 +205,7 @@ static int xml_parser_get_node (xml_node_t *current_node, char *root_name, int r
/* avoid a memory leak */
free(current_node->data);
}
- current_node->data = strdup(tok);
+ current_node->data = lexer_decode_entities(tok);
lprintf("info: node data : %s\n", current_node->data);
break;
default:
@@ -389,7 +389,7 @@ static int xml_parser_get_node (xml_node_t *current_node, char *root_name, int r
current_property = current_property->next;
}
current_property->name = strdup(property_name);
- current_property->value = strdup(tok);
+ current_property->value = lexer_decode_entities(tok);
lprintf("info: new property %s=%s\n", current_property->name, current_property->value);
state = 2;
break;
@@ -523,6 +523,40 @@ int xml_parser_get_property_bool (xml_node_t *node, const char *name,
return 0;
}
+static int xml_escape_string_internal (char *buf, const char *s,
+ xml_escape_quote_t quote_type)
+{
+ int c, length = 0;
+ int sl = buf ? 8 : 0;
+ /* calculate max required buffer size */
+ while ((c = *s++ & 0xFF))
+ switch (c)
+ {
+ case '"': if (quote_type != XML_ESCAPE_DOUBLE_QUOTE) goto literal;
+ length += snprintf (buf + length, sl, "&quot;"); break;
+ case '\'': if (quote_type != XML_ESCAPE_SINGLE_QUOTE) goto literal;
+ length += snprintf (buf + length, sl, "&apos;"); break;
+ case '&': length += snprintf (buf + length, sl, "&amp;"); break;
+ case '<': length += snprintf (buf + length, sl, "&lt;"); break;
+ case '>': length += snprintf (buf + length, sl, "&gt;"); break;
+ case 127: length += snprintf (buf + length, sl, "&#127;"); break;
+ case '\t':
+ case '\n':
+ literal: if (buf) buf[length] = c; ++length; break;
+ default: if (c >= ' ') goto literal;
+ length += snprintf (buf + length, sl, "&#%d;", c); break;
+ }
+ if (buf)
+ buf[length] = 0;
+ return length + 1;
+}
+
+char *xml_escape_string (const char *s, xml_escape_quote_t quote_type)
+{
+ char *buf = xine_xmalloc (xml_escape_string_internal (NULL, s, quote_type));
+ return buf ? (xml_escape_string_internal (buf, s, quote_type), buf) : NULL;
+}
+
static void printf_indent (int indent, const char *format, ...) {
int i ;
@@ -550,7 +584,9 @@ static void xml_parser_dump_node (xml_node_t *node, int indent) {
p = node->props;
while (p) {
- printf ("%s='%s'", p->name, p->value);
+ char *value = xml_escape_string (p->value, XML_ESCAPE_SINGLE_QUOTE);
+ printf ("%s='%s'", p->name, value);
+ free (value);
p = p->next;
if (p) {
printf ("\n");
diff --git a/src/xine-utils/xmlparser.h b/src/xine-utils/xmlparser.h
index ccf982f66..45217d3f9 100644
--- a/src/xine-utils/xmlparser.h
+++ b/src/xine-utils/xmlparser.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: xmlparser.h,v 1.2 2003/07/19 00:22:43 tmattern Exp $
+ * $Id: xmlparser.h,v 1.3 2005/01/16 17:51:04 dsalt Exp $
*
*/
#ifndef XML_PARSER_H
@@ -60,6 +60,18 @@ int xml_parser_get_property_int (xml_node_t *node, const char *name,
int xml_parser_get_property_bool (xml_node_t *node, const char *name,
int def_value);
+/* for output:
+ * returns an escaped string (free() it when done)
+ * input must be in ASCII or UTF-8
+ */
+
+typedef enum {
+ XML_ESCAPE_NO_QUOTE,
+ XML_ESCAPE_SINGLE_QUOTE,
+ XML_ESCAPE_DOUBLE_QUOTE
+} xml_escape_quote_t;
+char *xml_escape_string (const char *s, xml_escape_quote_t quote_type);
+
/* for debugging purposes: dump read-in xml tree in a nicely
* indented fashion
*/