diff --git a/NEWS b/NEWS index f40c6dfd8da6..190c6c16a935 100644 --- a/NEWS +++ b/NEWS @@ -78,6 +78,8 @@ PHP NEWS - SOAP: . Fixed bug GH-22585 (OOM on bailout with uninitialized do_request() parameters). (David Carlier) + . Fixed xsd:hexBinary decoding to reject odd-length values instead of + silently truncating the last nibble. (Weilin Du) - Standard: . Fixed sleep() and usleep() to reject values that overflow the underlying diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c index e474798df6da..301cdd8588b4 100644 --- a/ext/soap/php_encoding.c +++ b/ext/soap/php_encoding.c @@ -766,6 +766,7 @@ static zval *to_zval_base64(zval *ret, encodeTypePtr type, xmlNodePtr data) static zval *to_zval_hexbin(zval *ret, encodeTypePtr type, xmlNodePtr data) { zend_string *str; + size_t content_len; size_t i, j; unsigned char c; @@ -778,7 +779,12 @@ static zval *to_zval_hexbin(zval *ret, encodeTypePtr type, xmlNodePtr data) soap_error0(E_ERROR, "Encoding: Violation of encoding rules"); return ret; } - str = zend_string_alloc(strlen((char*)data->children->content) / 2, 0); + content_len = strlen((char*) data->children->content); + if (content_len % 2 != 0) { + soap_error0(E_ERROR, "Encoding: Violation of encoding rules"); + return ret; + } + str = zend_string_alloc(content_len / 2, 0); for (i = j = 0; i < ZSTR_LEN(str); i++) { c = data->children->content[j++]; if (c >= '0' && c <= '9') { diff --git a/ext/soap/tests/hexbin_odd_length.phpt b/ext/soap/tests/hexbin_odd_length.phpt new file mode 100644 index 000000000000..bfe84ab643db --- /dev/null +++ b/ext/soap/tests/hexbin_odd_length.phpt @@ -0,0 +1,37 @@ +--TEST-- +SOAP rejects odd-length xsd:hexBinary values +--EXTENSIONS-- +soap +--FILE-- + + + + + ABC + + + +XML; + } +} + +$client = new TestSoapClient(null, [ + 'location' => 'test://', + 'uri' => 'urn:test', + 'exceptions' => true, +]); + +try { + var_dump(bin2hex($client->test())); +} catch (SoapFault $e) { + echo $e->faultstring, "\n"; +} +?> +--EXPECT-- +SOAP-ERROR: Encoding: Violation of encoding rules