Skip to content

ext/soap silently accepts out-of-range XML Schema integer values due to atoi() #22167

@LamentXU123

Description

@LamentXU123

Description

Now, ext/soap/php_schema.c uses atoi() when parsing several XML Schema integer fields. e.g. https://github.com/php/php-src/blob/master/ext/soap/php_schema.c#L1019,
https://github.com/php/php-src/blob/master/ext/soap/php_schema.c#L1029

This makes it silently accepts some out-of-range integer. After test, the following XML schema have this issue:

<xsd:element name="x" type="xsd:string" minOccurs="2147483648"/>
<xsd:element name="x" type="xsd:string" maxOccurs="2147483648"/>
<xsd:maxExclusive value="2147483648"/>
<xsd:maxInclusive value="2147483648"/>
<xsd:totalDigits value="2147483648"/>
<xsd:fractionDigits value="2147483648"/>
<xsd:length value="2147483648"/>
<xsd:minLength value="2147483648"/>
<xsd:maxLength value="2147483648"/>

POC:

<?php
$wsdl = <<<'XML'
<?xml version="1.0"?>
<definitions
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:tns="http://test-uri/"
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
    xmlns="http://schemas.xmlsoap.org/wsdl/"
    targetNamespace="http://test-uri/">
<types>
    <xsd:schema targetNamespace="http://test-uri/">
    <xsd:complexType name="T">
        <xsd:sequence>
        <xsd:element name="x" type="xsd:string" maxOccurs="2147483648"/>
        </xsd:sequence>
    </xsd:complexType>
    </xsd:schema>
</types>
<message name="m"><part name="p" type="tns:T"/></message>
<portType name="p"><operation name="op"><input message="tns:m"/></operation></portType>
<binding name="b" type="tns:p">
    <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
    <operation name="op"><soap:operation soapAction="#op"/>  <input>
    <soap:body use="encoded"
               namespace="http://test-uri/"
               encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
  </input></operation>
</binding>
<service name="s"><port name="p" binding="tns:b"><soap:address location="test://"/></port></service>
</definitions>
XML;

$file = tempnam(sys_get_temp_dir(), 'wsdl');
file_put_contents($file, $wsdl);

try {
    new SoapClient($file, ['cache_wsdl' => WSDL_CACHE_NONE]);
    echo "parsed\n";
} catch (SoapFault $e) {
    echo $e->getMessage(), "\n";
}

unlink($file);

With maxOccurs="2147483648" which is bigger than PHP_INT_MAX, it shouldn't be passed. Now the behavior is passing this silently, while I am expecting

SOAP-ERROR: Parsing Schema: maxOccurs value is out of range

PHP Version

all supported versions

Operating System

N/A

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions