Mantis - Quercus
Viewing Issue Advanced Details
2353 minor always 01-22-08 08:17 01-23-08 11:56
ferg  
nam  
normal  
closed 3.1.4  
fixed  
none    
none 3.1.5  
0002353: xml_parse_into_struct
(rep by Ries van Twisk)

when using xml_parse_into_struct I noticed that I get an java
exception on empty or mis formed XML values,
this include an empty strings.

(Latest version of resin from SVN):

Below the mail with a PHP with various options to repeat

The solve this issue the best thing is not to throw an exception but
return 0, this will make the parse_into_struct more behave like PP.

I also did notice that PHP will never throw an exception even when I
put the parse_into_struct function in a
try/catch block. PHP simply returns 0 on invalid XML's

I have two notices:
1) PHP will parse an XML correctly even though the XML is invalid!!
This can be seen in test 3,5,7,8
2) levels are of the type float in resin this should be integer.

For both notices I don't think this is a great deal. For one thing if
a XML is send to PHP, then it should be good to start off with (except
empty strings may be).
Floats and integers can be compared easy in PHP.... However I am not
sure if any PHP script does a isFloat() on that value.


Test PHp script, enable each $string line to test
<?php
//TEST 1-
//mod_php:int(0) array(0) {
//resin:com.caucho.quercus.QuercusModuleException:
java.lang.Exception: Content
$string = 'a ';
//TEST 2-
//mod_php:int(1) array(1) { [0]=> array(4) { ["tag"]=> string(1)
"a" ["type"]=> string(8) "complete" ["level"]=> int(1) ["value"]=>
string(1) "A" } }
//resin:int(1) array(1) { [0]=> array(4) { ["tag"]=> string(1)
"a" ["type"]=> string(8) "complete" ["level"]=> float(1) ["value"]=>
string(1) "A" } }
//$string = '<a>A</a>';
//TEST 3-
//mod_php:int(0) array(1) { [0]=> array(4) { ["tag"]=> string(1)
"a" ["type"]=> string(8) "complete" ["level"]=> int(1) ["value"]=>
string(1) "A" }
//resin:com.caucho.quercus.QuercusModuleException:
java.lang.Exception: Content
//$string = ' <a>A</a> > ';
//TEST 4-
//mod_php:int(1) array(1) { [0]=> array(4) { ["tag"]=> string(1)
"a" ["type"]=> string(8) "complete" ["level"]=> int(1) ["value"]=>
string(1) "A" } }
//resin:int(1) array(1) { [0]=> array(4) { ["tag"]=> string(1)
"a" ["type"]=> string(8) "complete" ["level"]=> float(1) ["value"]=>
string(1) "A" } }
//$string = ' <a>A</a> ';
//TEST 5-
//mod_php:int(0) array(1) { [0]=> array(4) { ["tag"]=> string(1)
"a" ["type"]=> string(8) "complete" ["level"]=> int(1) ["value"]=> //
string(1) "A" } }
//resin:com.caucho.quercus.QuercusModuleException:
java.lang.Exception: Content
//$string = ' <a>A</a> a ';
//TEST 6-
//mod_php:int(0) array(0) { }
//resin:com.caucho.quercus.QuercusModuleException:
java.lang.Exception: Premature
//$string = ' ';
//TEST 7-
//mod_php:int(0) array(1) { [0]=> array(3) { ["tag"]=> string(1)
"a" ["type"]=> string(8) "complete" ["level"]=> int(1) } }
//resin:com.caucho.quercus.QuercusModuleException:
java.lang.Exception: The markup
//$string = ' <a></a> < ';
//TEST 8-
//mod_php:int(0) array(1) { [0]=> array(3) { ["tag"]=> string(1)
"a" ["type"]=> string(8) "complete" ["level"]=> int(1) }
//resin:com.caucho.quercus.QuercusModuleException:
java.lang.Exception: The markup
$string = ' <a></a> ';
//TEST 9-
//mod_php:int(1) array(3) { [0]=> array(3) { ["tag"]=> string(1)
"a" ["type"]=> string(4) "open" ["level"]=> int(1) } [1]=> array(3)
{ ["tag"]=> string(1) "b" ["type"]=> string(8) "complete" ["level"]=>
int(2) } [2]=> array(3) { ["tag"]=> string(1) "a" ["type"]=> string(5)
"close" ["level"]=> int(1) }
//resin:int(1) array(3) { [0]=> array(3) { ["tag"]=> string(1)
"a" ["type"]=> string(4) "open" ["level"]=> float(1) } [1]=> array(3)
{ ["tag"]=> string(1) "b" ["type"]=> string(8) "complete" ["level"]=>
float(2) } [2]=> array(3) { ["tag"]=> string(1) "a" ["type"]=>
string(5) "close" ["level"]=> float(1) } }
$string = ' <a></a> ';





$parser = xml_parser_create();
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 0);
$value = xml_parse_into_struct($parser, $string, $vals, $index);
var_dump($value);
xml_parser_free($parser);
var_dump($vals);

?>




before:
   public int xml_parse_into_struct(String data,
                                    @Reference Value valsV,
                                    @Optional @Reference Value indexV)
     throws Exception
   {
     _xmlString.append(data);

     InputSource is = new InputSource(new
StringReader(_xmlString.toString()));

     ArrayValueImpl valueArray = new ArrayValueImpl();
     ArrayValueImpl indexArray = new ArrayValueImpl();

     try {
       SAXParser saxParser = _factory.newSAXParser();
       saxParser.parse(is, new StructHandler(valueArray, indexArray));
     } catch (Exception ex) {
       log.log(Level.FINE, ex.toString(), ex);
       throw new Exception(L.l(ex.getMessage()));
     }

     valsV.set(valueArray);
     indexV.set(indexArray);

     return 1;
   }

after (simply return 0 on invalid XML instead of an exception):

   public int xml_parse_into_struct(String data,
                                    @Reference Value valsV,
                                    @Optional @Reference Value indexV)
     throws Exception
   {
     _xmlString.append(data);

     InputSource is = new InputSource(new
StringReader(_xmlString.toString()));

     ArrayValueImpl valueArray = new ArrayValueImpl();
     ArrayValueImpl indexArray = new ArrayValueImpl();

     try {
       SAXParser saxParser = _factory.newSAXParser();
       saxParser.parse(is, new StructHandler(valueArray, indexArray));
     } catch (Exception ex) {
       log.log(Level.FINE, ex.toString(), ex);
       return 0; // Don't throw an exception but return 0, this is
also what PHP does
     }

     valsV.set(valueArray);
     indexV.set(indexArray);

     return 1;
   }


Notes
(0002669)
nam   
01-23-08 11:56   
php/1h0[f-h]

Quercus will now fail silently on invalid xml. Quercus still returns "levels" as floats because that is how PHP does it.