diff --git a/src/modules/spider/xml.c b/src/modules/spider/xml.c index 41ccdc58ed4805d07d681906125d9fa11d5b4082..3e977498dcb55dfc90e7701f495727a05726efa7 100644 --- a/src/modules/spider/xml.c +++ b/src/modules/spider/xml.c @@ -37,6 +37,7 @@ struct xmlinput ptrdiff_t pos; struct mapping *callbackinfo; struct pike_string *to_free; + struct pike_string *entity; }; BLOCK_ALLOC(xmlinput, 64) @@ -684,6 +685,14 @@ ISWRAP(isHexChar) #define POP() do { \ struct xmlinput *i=data->input.next; \ IF_XMLDEBUG(fprintf(stderr,"SMEG POP\n")); \ + if (data->input.entity) { \ + if (data->input.to_free) { \ + mapping_string_insert_string(THIS->entities, \ + data->input.entity, \ + data->input.to_free); \ + } \ + free_string(data->input.entity); \ + } \ if(data->input.to_free) free_string(data->input.to_free); \ if(data->input.callbackinfo) free_mapping(data->input.callbackinfo); \ data->input=*i; \ @@ -1152,7 +1161,9 @@ static int read_smeg_pereference(struct xmldata *data) }else{ struct mapping *callbackinfo; struct pike_string *name=0; - ONERROR tmp3,tmp4; + struct pike_string *full_name=0; + int external_entity_value=0; + ONERROR tmp3,tmp4,tmp5; push_constant_text("%"); SIMPLE_READNAME(); @@ -1161,6 +1172,9 @@ static int read_smeg_pereference(struct xmldata *data) SET_ONERROR(tmp3, do_free_string, name); f_add(2); + add_ref(full_name=sp[-1].u.string); + SET_ONERROR(tmp5, do_free_string, full_name); + if(PEEK(0)!=';') XMLERROR("Missing ';' after parsed entity reference."); READ(1); @@ -1182,6 +1196,7 @@ static int read_smeg_pereference(struct xmldata *data) do { if(UNSAFE_IS_ZERO(sp-1)) { + external_entity_value = 1; pop_stack(); push_constant_text("%"); ref_push_string(name); @@ -1202,19 +1217,28 @@ static int read_smeg_pereference(struct xmldata *data) XMLERROR("XML->__entities value is not a string!"); }else{ struct pike_string *s=sp[-1].u.string; - struct xmlinput *i=alloc_xmlinput(); IF_XMLDEBUG(fprintf(stderr, "ptr=%p len=%d pos=%d to_free=%p\n", data->input.datap.ptr, data->input.len, data->input.pos, data->input.to_free)); - *i=data->input; - data->input.next=i; - data->input.pos=0; - data->input.datap=MKPCHARP_STR(s); - data->input.len=(s)->len; - data->input.callbackinfo=callbackinfo; + /* PUSH(s) */ + { + struct xmlinput *i=alloc_xmlinput(); + *i=data->input; + data->input.next=i; + data->input.pos=0; + data->input.datap=MKPCHARP_STR(s); + data->input.len=(s)->len; + data->input.callbackinfo=callbackinfo; + copy_shared_string(data->input.to_free,s); + if (external_entity_value || !full_name) { + data->input.entity = 0; + } else { + copy_shared_string(data->input.entity, full_name); + } + } + CALL_AND_UNSET_ONERROR(tmp5); UNSET_ONERROR(tmp4); - copy_shared_string(data->input.to_free,s); READ(0); /* autopop empty strings */ pop_stack(); @@ -1223,6 +1247,7 @@ static int read_smeg_pereference(struct xmldata *data) } }while(0); + CALL_AND_UNSET_ONERROR(tmp5); CALL_AND_UNSET_ONERROR(tmp4); CALL_AND_UNSET_ONERROR(tmp3); } @@ -2701,6 +2726,7 @@ static void parse_xml(INT32 args) data.input.len=s->len; data.input.pos=0; data.input.to_free=0; + data.input.entity=0; data.input.callbackinfo=allocate_mapping(0); data.input.next=0; data.func=sp+1-args; @@ -2775,6 +2801,7 @@ static void define_entity(INT32 args) data.input.len=s->len; data.input.pos=0; data.input.to_free=0; + data.input.entity=0; data.input.callbackinfo=allocate_mapping(0); data.func=sp+2-args; data.extra_args=sp+3-args; @@ -2821,6 +2848,7 @@ static void parse_dtd(INT32 args) data.input.len=s->len; data.input.pos=0; data.input.to_free=0; + data.input.entity=0; data.input.callbackinfo=allocate_mapping(0); data.func=sp+1-args; data.extra_args=sp+2-args;