@@ -37,18 +37,34 @@ static int php_libxml_svg_stream_read(void *context, char *buffer, int len)
3737
3838/* Sanity check that the input only contains characters valid for a dimension (numbers with units, e.g. 5cm).
3939 * This also protects the user against injecting XSS.
40- * Only accept [0-9a -zA-Z] */
41- static bool php_libxml_valid_dimension (const xmlChar * input )
40+ * Only accept [0-9]+[a -zA-Z]* */
41+ static bool php_libxml_parse_dimension (const xmlChar * input , const xmlChar * * unit_position )
4242{
43- if (* input == '\0' ) {
43+ if (!( * input >= '0' && * input <= '9' ) ) {
4444 return false;
4545 }
46+
47+ input ++ ;
48+
49+ while (* input ) {
50+ if (!(* input >= '0' && * input <= '9' )) {
51+ if ((* input >= 'a' && * input <= 'z' ) || (* input >= 'A' && * input <= 'Z' )) {
52+ break ;
53+ }
54+ return false;
55+ }
56+ input ++ ;
57+ }
58+
59+ * unit_position = input ;
60+
4661 while (* input ) {
47- if (!((* input >= '0' && * input <= '9' ) || ( * input >= ' a' && * input <= 'z' ) || (* input >= 'A' && * input <= 'Z' ))) {
62+ if (!((* input >= 'a' && * input <= 'z' ) || (* input >= 'A' && * input <= 'Z' ))) {
4863 return false;
4964 }
5065 input ++ ;
5166 }
67+
5268 return true;
5369}
5470
@@ -93,7 +109,10 @@ zend_result php_libxml_svg_image_handle(php_stream *stream, struct php_gfxinfo *
93109
94110 xmlChar * width = xmlTextReaderGetAttribute (reader , BAD_CAST "width" );
95111 xmlChar * height = xmlTextReaderGetAttribute (reader , BAD_CAST "height" );
96- if (!width || !height || !php_libxml_valid_dimension (width ) || !php_libxml_valid_dimension (height )) {
112+ const xmlChar * width_unit_position , * height_unit_position ;
113+ if (!width || !height
114+ || !php_libxml_parse_dimension (width , & width_unit_position )
115+ || !php_libxml_parse_dimension (height , & height_unit_position )) {
97116 xmlFree (width );
98117 xmlFree (height );
99118 break ;
@@ -102,8 +121,16 @@ zend_result php_libxml_svg_image_handle(php_stream *stream, struct php_gfxinfo *
102121 is_svg = true;
103122 if (result ) {
104123 * result = ecalloc (1 , sizeof (* * result ));
105- (* result )-> width_str = zend_string_init ((const char * ) width , xmlStrlen (width ), false);
106- (* result )-> height_str = zend_string_init ((const char * ) height , xmlStrlen (height ), false);
124+ (* result )-> width = ZEND_STRTOL ((const char * ) width , NULL , 10 );
125+ (* result )-> height = ZEND_STRTOL ((const char * ) height , NULL , 10 );
126+ if (* width_unit_position ) {
127+ (* result )-> width_unit = zend_string_init ((const char * ) width_unit_position ,
128+ xmlStrlen (width_unit_position ), false);
129+ }
130+ if (* height_unit_position ) {
131+ (* result )-> height_unit = zend_string_init ((const char * ) height_unit_position ,
132+ xmlStrlen (height_unit_position ), false);
133+ }
107134 }
108135
109136 xmlFree (width );
0 commit comments