Menu

#78 i8 type not supported

release_1.0
closed
9
2016-06-26
2009-12-11
No

XMLRPC call FAILED!
Fault code: [2] Reason: 'Invalid return payload: enable debugging to examine incoming payload xmlrpc element I8 cannot be child of VALUE'

Debug info:

---SENDING---
POST /RPC_PATH HTTP/1.0
User-Agent: XML-RPC for PHP 3.0.0.beta
Host: myhost:80
Accept-Charset: UTF-8,ISO-8859-1,US-ASCII
Content-Type: text/xml
Content-Length: 102

<methodCall> <methodName>system.pid</methodName> <params></params> </methodCall> ---END--- ---GOT--- HTTP/1.1 200 OK Date: Fri, 11 Dec 2009 15:08:43 GMT Server: Apache/2.2.13 (Fedora) X-Accept-TimeURI: application/x-annodex Content-Length: 144 Connection: close Content-Type: text/xml Expires: Fri, 11 Dec 2009 15:08:43 GMT <methodResponse> <params> <param><value><i8>17241</i8></value></param> </params> </methodResponse>

---END---
HEADER: date: Fri, 11 Dec 2009 15:08:43 GMT
HEADER: server: Apache/2.2.13 (Fedora)
HEADER: x-accept-timeuri: application/x-annodex
HEADER: content-length: 144
HEADER: connection: close
HEADER: content-type: text/xml
HEADER: expires: Fri, 11 Dec 2009 15:08:43 GMT

Discussion

  • Radu Alexandru Popescu

    Apparently, PHP integers are 32bit signed on x86 and 64bit signed on x86_64...
    The size of the PHP integer can be read using PHP_INT_SIZE.
    This imposes a hack for running PHPXMLRPC on x86 and also supporting 64 bit integers.

     
  • Gaetano Giunta

    Gaetano Giunta - 2009-12-28

    FYI, i8 is not part of the xml-rpc standard - it might be getting more and more widespread, but I fear there might be discord over its implementation (eg. http://ws.apache.org/xmlrpc/types.html lists a different tag: ex:i8).

    This means I will try to implement this feature, but with a lower priority than bugs
    - taking into account 32bit limitations
    - using a similar api to what has been implemented for the nil stuff

    The first question arising is: what to do when receiving an i8 and php is compiled in 32 bit? At first thought, I'd say always throwing an error (even if the int is actually smallish) is the best option...

     
  • Radu Alexandru Popescu

    I apologize. I was not aware of the i8 sittuation.

    Now regarding the handling of the i8 type on 32bit platforms, I was thinking of creating separate implementations of the xmlrpc.inc file for 32bit platforms (xmlrpc_32bit.inc) and for 64bit platforms (xmlrpc_64bit.inc), but both having the same classes with the same names.
    Then use the following code in a xmlrpc.inc file:
    <?php
    if(PHP_INT_SIZE > 4) {
    require_once("xmlrpc_64bit.inc");
    } else {
    require_once("xmlrpc_32bit.inc");
    }
    ?>

    For the handling of the i8 on 32bit case, it kind of depends on how the value is used after parsing... If one intends on just displaying the values, then handling it as a string is ok. But if one intends on doing arithmetics with these values, then you kind of have a problem.
    I was thinking of something along the lines of this:
    <?php
    /
    This example pressumes that $val = "17241" from
    <?xml version="1.0" encoding="UTF-8"?>
    <methodResponse>
    <params>
    <param><value><i8>17241</i8></value></param>
    </params>
    </methodResponse>
    /
    $intval = (int)$val;
    if($val != "$intval") {
    throw new InvalidIntegerSizeException();
    // alternatly you could return
    // a bcmath resource ( http://www.php.net/manual/en/ref.bc.php )
    // or something simmilar
    // http://www.php.net/manual/en/refs.math.php
    } else {
    return $intval;
    }
    ?>

    I am curios to know what are your thoughts on my ideeas.

    P.S.: Happy New Year!

     
  • Gaetano Giunta

    Gaetano Giunta - 2010-01-10

    I am not too fond of adding 2 extra files and radically changing the contents of xmlrpc.inc - after all this lib has been around for a long, long time, and its main advantage right now is probably stability.
    I'd rather either include handling of i8 in the main branch (but it could be quite a lot of extra IFs), or just add a separate xmlrpc_i8.inc file. Then the users who want both could simply add the bit of code you presented to do dynamic inclusion if they want.

    As for raising an exception, it is a good idea, but we can assume that 64bit ints are either supported or not. Since this is a setting that can only be changed at compilation time, we might as well just assume that they are when the user goes for xmlrpc_i8.inc and skip the test...

     
  • Exceeder

    Exceeder - 2010-09-27

    Hello,

    adding i8 support does only take 2 minutes of time. I already did this for version 2.2. Just search for i4 in the xmlrpc.inc and add i8. The php datatype must be double. This works for php 32 and 64 bit without any problems and does not touch the stability of all existing datatypes or the rest of the implementation, the worst case would be, that i8 does not work properly in some situations (but i did not find any).

     
  • Gaetano Giunta

    Gaetano Giunta - 2010-09-27

    You need to add 'i8' to $GLOBALS['xmlrpc_valid_parents']

     
  • Exceeder

    Exceeder - 2010-09-27

    Hi,

    just adding this line is not enough. Special handling for the i8 datatype must me implemented. Does it help you, when I add i8 support to xmlrpc.inc? I can send you the modified version. I really would like to have this in the official version.

     
  • Gaetano Giunta

    Gaetano Giunta - 2010-09-27

    Of course you are welcome to send your code. I am not promising anything though... ;-)

     
  • Exceeder

    Exceeder - 2010-09-27

    Okay, I'm new to sourceforge. How should I send my modified file?

     
  • Gaetano Giunta

    Gaetano Giunta - 2010-09-27

    You can use the 'send me a message' button on my profile page, or just post the complete code in a comment here

     
  • Exceeder

    Exceeder - 2010-09-27

    Okay, here is the diff for you. Please tell me, if you need the complete file.

    --- D:/Web/xmlrpc/lib/xmlrpc.3.0.0.beta.inc Sa Sep 5 23:33:18 2009
    +++ D:/Web/xmlrpc/lib/xmlrpc.inc Mo Sep 27 14:15:45 2010
    @@ -50,6 +50,7 @@
    // Milosch: 2005/08/07 - explicitly request these via $GLOBALS where used.
    $GLOBALS['xmlrpcI4']='i4';
    $GLOBALS['xmlrpcInt']='int';
    + $GLOBALS['xmlrpcI8']='i8';
    $GLOBALS['xmlrpcBoolean']='boolean';
    $GLOBALS['xmlrpcDouble']='double';
    $GLOBALS['xmlrpcString']='string';
    @@ -62,6 +63,7 @@
    $GLOBALS['xmlrpcTypes']=array(
    $GLOBALS['xmlrpcI4'] => 1,
    $GLOBALS['xmlrpcInt'] => 1,
    + $GLOBALS['xmlrpcI8'] => 1,
    $GLOBALS['xmlrpcBoolean'] => 1,
    $GLOBALS['xmlrpcString'] => 1,
    $GLOBALS['xmlrpcDouble'] => 1,
    @@ -76,6 +78,7 @@
    'BOOLEAN' => array('VALUE'),
    'I4' => array('VALUE'),
    'INT' => array('VALUE'),
    + 'I8' => array('VALUE'),
    'STRING' => array('VALUE'),
    'DOUBLE' => array('VALUE'),
    'DATETIME.ISO8601' => array('VALUE'),
    @@ -434,6 +437,7 @@
    break;
    case 'I4':
    case 'INT':
    + case 'I8':
    case 'STRING':
    case 'BOOLEAN':
    case 'DOUBLE':
    @@ -601,6 +605,7 @@
    case 'BOOLEAN':
    case 'I4':
    case 'INT':
    + case 'I8':
    case 'STRING':
    case 'DOUBLE':
    case 'DATETIME.ISO8601':
    @@ -663,6 +668,22 @@
    $GLOBALS['_xh']['value']=(double)$GLOBALS['_xh']['ac'];
    }
    }
    + elseif ($name=='I8')
    + {
    + // we have a I8
    + // we must check that only 0123456789-<space> are characters here
    + if (!preg_match('/^[+-]?[0123456789 \t]+$/', $GLOBALS['_xh']['ac']))
    + {
    + /// @todo: find a better way of throwing an error than this!
    + error_log('XML-RPC: non numeric value received in I8: '.$GLOBALS['_xh']['ac']);
    + $GLOBALS['_xh']['value']='ERROR_NON_NUMERIC_FOUND';
    + }
    + else
    + {
    + // it's ok, add it on
    + $GLOBALS['_xh']['value']=(double)$GLOBALS['_xh']['ac'];
    + }
    + }
    else
    {
    // we have an I4/INT
    @@ -2729,6 +2750,7 @@
    break;
    case 'i4':
    case 'int':
    + case 'i8':
    case 'double':
    case 'string':
    case 'boolean':
    @@ -2946,6 +2968,9 @@
    case $GLOBALS['xmlrpcI4']:
    $rs.="<${typ}>".(int)$val."";
    break;
    + case $GLOBALS['xmlrpcI8']:
    + $rs.="<${typ}>".(double)$val."";
    + break;
    case $GLOBALS['xmlrpcDouble']:
    // avoid using standard conversion of float to string because it is locale-dependent,
    // and also because the xmlrpc spec forbids exponential notation.

     
  • Exceeder

    Exceeder - 2010-09-27

    Hmm, sorry, but this is not working here. All spaces are stripped. I've opened a new issue and attached my diff file. The ID is 3076572.

     
  • Gaetano Giunta

    Gaetano Giunta - 2016-06-26

    Implemented!

     
  • Gaetano Giunta

    Gaetano Giunta - 2016-06-26
    • status: open --> closed
    • Group: --> release_1.0
     

Anonymous
Anonymous

Add attachments
Cancel