mirror of
https://github.com/processone/ejabberd.git
synced 2024-06-12 21:52:07 +02:00
Do not accept XML with undefined prefixes (EJAB-680)
This commit is contained in:
parent
5a0cfe7e2b
commit
84c1cf8033
|
@ -35,6 +35,7 @@
|
||||||
#define PARSE_FINAL_COMMAND 1
|
#define PARSE_FINAL_COMMAND 1
|
||||||
|
|
||||||
ei_x_buff event_buf;
|
ei_x_buff event_buf;
|
||||||
|
ei_x_buff xmlns_buf;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ErlDrvPort port;
|
ErlDrvPort port;
|
||||||
|
@ -43,6 +44,32 @@ typedef struct {
|
||||||
|
|
||||||
static XML_Memory_Handling_Suite ms = {driver_alloc, driver_realloc, driver_free};
|
static XML_Memory_Handling_Suite ms = {driver_alloc, driver_realloc, driver_free};
|
||||||
|
|
||||||
|
void encode_name(const XML_Char *name)
|
||||||
|
{
|
||||||
|
char *name_start;
|
||||||
|
char *prefix_start;
|
||||||
|
char *buf;
|
||||||
|
int name_len, prefix_len, buf_len;
|
||||||
|
|
||||||
|
if ((name_start = strchr(name, '\n'))) {
|
||||||
|
if ((prefix_start = strchr(name_start+1, '\n'))) {
|
||||||
|
name_len = prefix_start - name_start;
|
||||||
|
prefix_len = strlen(prefix_start+1);
|
||||||
|
buf_len = prefix_len + name_len;
|
||||||
|
buf = driver_alloc(buf_len);
|
||||||
|
memcpy(buf, prefix_start+1, prefix_len);
|
||||||
|
memcpy(buf+prefix_len, name_start, name_len);
|
||||||
|
buf[prefix_len] = ':';
|
||||||
|
ei_x_encode_string_len(&event_buf, buf, buf_len);
|
||||||
|
driver_free(buf);
|
||||||
|
} else {
|
||||||
|
ei_x_encode_string(&event_buf, name_start+1);
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
ei_x_encode_string(&event_buf, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void *erlXML_StartElementHandler(expat_data *d,
|
void *erlXML_StartElementHandler(expat_data *d,
|
||||||
const XML_Char *name,
|
const XML_Char *name,
|
||||||
const XML_Char **atts)
|
const XML_Char **atts)
|
||||||
|
@ -53,7 +80,10 @@ void *erlXML_StartElementHandler(expat_data *d,
|
||||||
ei_x_encode_tuple_header(&event_buf, 2);
|
ei_x_encode_tuple_header(&event_buf, 2);
|
||||||
ei_x_encode_long(&event_buf, XML_START);
|
ei_x_encode_long(&event_buf, XML_START);
|
||||||
ei_x_encode_tuple_header(&event_buf, 2);
|
ei_x_encode_tuple_header(&event_buf, 2);
|
||||||
ei_x_encode_string(&event_buf, name);
|
encode_name(name);
|
||||||
|
ei_x_append(&event_buf, &xmlns_buf);
|
||||||
|
ei_x_free(&xmlns_buf);
|
||||||
|
ei_x_new(&xmlns_buf);
|
||||||
|
|
||||||
for (i = 0; atts[i]; i += 2) {}
|
for (i = 0; atts[i]; i += 2) {}
|
||||||
|
|
||||||
|
@ -64,7 +94,7 @@ void *erlXML_StartElementHandler(expat_data *d,
|
||||||
for (i = 0; atts[i]; i += 2)
|
for (i = 0; atts[i]; i += 2)
|
||||||
{
|
{
|
||||||
ei_x_encode_tuple_header(&event_buf, 2);
|
ei_x_encode_tuple_header(&event_buf, 2);
|
||||||
ei_x_encode_string(&event_buf, atts[i]);
|
encode_name(atts[i]);
|
||||||
ei_x_encode_string(&event_buf, atts[i+1]);
|
ei_x_encode_string(&event_buf, atts[i+1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,7 +110,7 @@ void *erlXML_EndElementHandler(expat_data *d,
|
||||||
ei_x_encode_list_header(&event_buf, 1);
|
ei_x_encode_list_header(&event_buf, 1);
|
||||||
ei_x_encode_tuple_header(&event_buf, 2);
|
ei_x_encode_tuple_header(&event_buf, 2);
|
||||||
ei_x_encode_long(&event_buf, XML_END);
|
ei_x_encode_long(&event_buf, XML_END);
|
||||||
ei_x_encode_string(&event_buf, name);
|
encode_name(name);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,12 +125,35 @@ void *erlXML_CharacterDataHandler(expat_data *d,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *erlXML_StartNamespaceDeclHandler(expat_data *d,
|
||||||
|
const XML_Char *prefix,
|
||||||
|
const XML_Char *uri)
|
||||||
|
{
|
||||||
|
int prefix_len;
|
||||||
|
char *buf;
|
||||||
|
|
||||||
|
ei_x_encode_list_header(&xmlns_buf, 1);
|
||||||
|
ei_x_encode_tuple_header(&xmlns_buf, 2);
|
||||||
|
if (prefix) {
|
||||||
|
prefix_len = strlen(prefix);
|
||||||
|
buf = driver_alloc(7 + prefix_len);
|
||||||
|
strcpy(buf, "xmlns:");
|
||||||
|
strcpy(buf+6, prefix);
|
||||||
|
ei_x_encode_string(&xmlns_buf, buf);
|
||||||
|
driver_free(buf);
|
||||||
|
} else {
|
||||||
|
ei_x_encode_string(&xmlns_buf, "xmlns");
|
||||||
|
};
|
||||||
|
ei_x_encode_string(&xmlns_buf, uri);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static ErlDrvData expat_erl_start(ErlDrvPort port, char *buff)
|
static ErlDrvData expat_erl_start(ErlDrvPort port, char *buff)
|
||||||
{
|
{
|
||||||
expat_data* d = (expat_data*)driver_alloc(sizeof(expat_data));
|
expat_data* d = (expat_data*)driver_alloc(sizeof(expat_data));
|
||||||
d->port = port;
|
d->port = port;
|
||||||
d->parser = XML_ParserCreate_MM("UTF-8", &ms, NULL);
|
d->parser = XML_ParserCreate_MM("UTF-8", &ms, "\n");
|
||||||
XML_SetUserData(d->parser, d);
|
XML_SetUserData(d->parser, d);
|
||||||
|
|
||||||
set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);
|
set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);
|
||||||
|
@ -112,6 +165,9 @@ static ErlDrvData expat_erl_start(ErlDrvPort port, char *buff)
|
||||||
XML_SetCharacterDataHandler(
|
XML_SetCharacterDataHandler(
|
||||||
d->parser, (XML_CharacterDataHandler)erlXML_CharacterDataHandler);
|
d->parser, (XML_CharacterDataHandler)erlXML_CharacterDataHandler);
|
||||||
|
|
||||||
|
XML_SetStartNamespaceDeclHandler(
|
||||||
|
d->parser, (XML_StartNamespaceDeclHandler) erlXML_StartNamespaceDeclHandler);
|
||||||
|
XML_SetReturnNSTriplet(d->parser, 1);
|
||||||
|
|
||||||
return (ErlDrvData)d;
|
return (ErlDrvData)d;
|
||||||
}
|
}
|
||||||
|
@ -138,6 +194,7 @@ static int expat_erl_control(ErlDrvData drv_data,
|
||||||
case PARSE_COMMAND:
|
case PARSE_COMMAND:
|
||||||
case PARSE_FINAL_COMMAND:
|
case PARSE_FINAL_COMMAND:
|
||||||
ei_x_new_with_version(&event_buf);
|
ei_x_new_with_version(&event_buf);
|
||||||
|
ei_x_new(&xmlns_buf);
|
||||||
res = XML_Parse(d->parser, buf, len, command == PARSE_FINAL_COMMAND);
|
res = XML_Parse(d->parser, buf, len, command == PARSE_FINAL_COMMAND);
|
||||||
|
|
||||||
if(!res)
|
if(!res)
|
||||||
|
@ -161,6 +218,7 @@ static int expat_erl_control(ErlDrvData drv_data,
|
||||||
memcpy(b->orig_bytes, event_buf.buff, size);
|
memcpy(b->orig_bytes, event_buf.buff, size);
|
||||||
|
|
||||||
ei_x_free(&event_buf);
|
ei_x_free(&event_buf);
|
||||||
|
ei_x_free(&xmlns_buf);
|
||||||
|
|
||||||
*rbuf = (char *)b;
|
*rbuf = (char *)b;
|
||||||
return size;
|
return size;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user