diff options
| author | Rob Richards <rrichards@php.net> | 2013-07-06 07:59:20 -0400 | 
|---|---|---|
| committer | Rob Richards <rrichards@php.net> | 2013-07-06 07:59:20 -0400 | 
| commit | e4a28b7b7b972fecd01458364c0663195352891e (patch) | |
| tree | c2ac8b084aa3f4c30878712f6d3989fe71bad939 | |
| parent | c652cc93ec5ce8f1833d023159804ebd56e1a94e (diff) | |
| parent | 7d163e8a0880ae8af2dd869071393e5dc07ef271 (diff) | |
| download | php-git-e4a28b7b7b972fecd01458364c0663195352891e.tar.gz | |
Merge branch 'PHP-5.3' into PHP-5.4
# By Rob Richards (1)
* PHP-5.3:
  truncate results at depth of 255 to prevent corruption
| -rw-r--r-- | ext/xml/xml.c | 90 | 
1 files changed, 50 insertions, 40 deletions
diff --git a/ext/xml/xml.c b/ext/xml/xml.c index 2fea4f8ab9..334938ab24 100644 --- a/ext/xml/xml.c +++ b/ext/xml/xml.c @@ -428,7 +428,7 @@ static void xml_parser_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC)  	}  	if (parser->ltags) {  		int inx; -		for (inx = 0; inx < parser->level; inx++) +		for (inx = 0; ((inx < parser->level) && (inx < XML_MAXLEVEL)); inx++)  			efree(parser->ltags[ inx ]);  		efree(parser->ltags);  	} @@ -805,45 +805,50 @@ void _xml_startElementHandler(void *userData, const XML_Char *name, const XML_Ch  		}   		if (parser->data) { -			zval *tag, *atr; -			int atcnt = 0; +			if (parser->level <= XML_MAXLEVEL)  { +				zval *tag, *atr; +				int atcnt = 0; -			MAKE_STD_ZVAL(tag); -			MAKE_STD_ZVAL(atr); +				MAKE_STD_ZVAL(tag); +				MAKE_STD_ZVAL(atr); -			array_init(tag); -			array_init(atr); +				array_init(tag); +				array_init(atr); -			_xml_add_to_info(parser,((char *) tag_name) + parser->toffset); +				_xml_add_to_info(parser,((char *) tag_name) + parser->toffset); -			add_assoc_string(tag,"tag",((char *) tag_name) + parser->toffset,1); /* cast to avoid gcc-warning */ -			add_assoc_string(tag,"type","open",1); -			add_assoc_long(tag,"level",parser->level); +				add_assoc_string(tag,"tag",((char *) tag_name) + parser->toffset,1); /* cast to avoid gcc-warning */ +				add_assoc_string(tag,"type","open",1); +				add_assoc_long(tag,"level",parser->level); -			parser->ltags[parser->level-1] = estrdup(tag_name); -			parser->lastwasopen = 1; +				parser->ltags[parser->level-1] = estrdup(tag_name); +				parser->lastwasopen = 1; -			attributes = (const XML_Char **) attrs; +				attributes = (const XML_Char **) attrs; -			while (attributes && *attributes) { -				att = _xml_decode_tag(parser, attributes[0]); -				val = xml_utf8_decode(attributes[1], strlen(attributes[1]), &val_len, parser->target_encoding); -				 -				add_assoc_stringl(atr,att,val,val_len,0); +				while (attributes && *attributes) { +					att = _xml_decode_tag(parser, attributes[0]); +					val = xml_utf8_decode(attributes[1], strlen(attributes[1]), &val_len, parser->target_encoding); -				atcnt++; -				attributes += 2; +					add_assoc_stringl(atr,att,val,val_len,0); -				efree(att); -			} +					atcnt++; +					attributes += 2; -			if (atcnt) { -				zend_hash_add(Z_ARRVAL_P(tag),"attributes",sizeof("attributes"),&atr,sizeof(zval*),NULL); -			} else { -				zval_ptr_dtor(&atr); -			} +					efree(att); +				} + +				if (atcnt) { +					zend_hash_add(Z_ARRVAL_P(tag),"attributes",sizeof("attributes"),&atr,sizeof(zval*),NULL); +				} else { +					zval_ptr_dtor(&atr); +				} -			zend_hash_next_index_insert(Z_ARRVAL_P(parser->data),&tag,sizeof(zval*),(void *) &parser->ctag); +				zend_hash_next_index_insert(Z_ARRVAL_P(parser->data),&tag,sizeof(zval*),(void *) &parser->ctag); +			} else if (parser->level == (XML_MAXLEVEL + 1)) { +				TSRMLS_FETCH(); +				php_error_docref(NULL TSRMLS_CC, E_WARNING, "Maximum depth exceeded - Results truncated"); +			}  		}  		efree(tag_name); @@ -895,7 +900,7 @@ void _xml_endElementHandler(void *userData, const XML_Char *name)  		efree(tag_name); -		if (parser->ltags) { +		if ((parser->ltags) && (parser->level <= XML_MAXLEVEL)) {  			efree(parser->ltags[parser->level-1]);  		} @@ -979,18 +984,23 @@ void _xml_characterDataHandler(void *userData, const XML_Char *s, int len)  						}  					} -					MAKE_STD_ZVAL(tag); -					 -					array_init(tag); -					 -					_xml_add_to_info(parser,parser->ltags[parser->level-1] + parser->toffset); +					if (parser->level <= XML_MAXLEVEL) { +						MAKE_STD_ZVAL(tag); + +						array_init(tag); -					add_assoc_string(tag,"tag",parser->ltags[parser->level-1] + parser->toffset,1); -					add_assoc_string(tag,"value",decoded_value,0); -					add_assoc_string(tag,"type","cdata",1); -					add_assoc_long(tag,"level",parser->level); +						_xml_add_to_info(parser,parser->ltags[parser->level-1] + parser->toffset); -					zend_hash_next_index_insert(Z_ARRVAL_P(parser->data),&tag,sizeof(zval*),NULL); +						add_assoc_string(tag,"tag",parser->ltags[parser->level-1] + parser->toffset,1); +						add_assoc_string(tag,"value",decoded_value,0); +						add_assoc_string(tag,"type","cdata",1); +						add_assoc_long(tag,"level",parser->level); + +						zend_hash_next_index_insert(Z_ARRVAL_P(parser->data),&tag,sizeof(zval*),NULL); +					} else if (parser->level == (XML_MAXLEVEL + 1)) { +						TSRMLS_FETCH(); +						php_error_docref(NULL TSRMLS_CC, E_WARNING, "Maximum depth exceeded - Results truncated"); +					}  				}  			} else {  				efree(decoded_value);  | 
