The XML-RPC server included in drupal core doesn't define the character set that is used to encode the XML.

In our setup a ruby XML-RPC client crashes if the XML document returned by drupal contains German umlauts. The reason is, that drupal uses UTF-8 but the ruby client doesn't realize that.

The issue exists in all drupal versions. I'll provide patches for all versions.

Comments

mkalkbrenner’s picture

Status: Active » Needs review
StatusFileSize
new698 bytes

Patch for drupal 8.x

mstiem’s picture

Status: Needs review » Reviewed & tested by the community

Had a problem with the missing charset definition. My regex on my client crashed often by transmitting ä,ö,ü ect. over XML-RPC. After adding the missing code in XML-RPC everything worked fine.

fgm’s picture

Status: Reviewed & tested by the community » Needs review
StatusFileSize
new1.06 KB

Looks good to me, but while we're at it we could also fix a long standing issue with some weak old parsers which don't like missing a space between an attribute and a PI termination.

Resetting to CNR to trigger the bot, but otherwise RTBC for me.

mkalkbrenner’s picture

Status: Needs review » Reviewed & tested by the community

Test bot succeeded. RTBC

webchick’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs backport to D6, +Needs tests, +Needs backport to D7

Is it possible to write a test for this?

Also, marking for backport to D7 and D6, per the OP.

mkalkbrenner’s picture

I'm not yet familiar with tests for Drupal 8 based on Symfony.
There seems to be something appropriate in core/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Tests/ResponseTest.php

    public function testContentTypeCharset()
    {
        $response = new Response();
        $response->headers->set('Content-Type', 'text/css');

        // force fixContentType() to be called
        $response->prepare(new Request());

        $this->assertEquals('text/css; charset=UTF-8', $response->headers->get('Content-Type'));
    }

But other parts of core deal with the same problem. For example the aggregator module:

function theme_aggregator_page_opml($variables) {
  $feeds = $variables['feeds'];

  drupal_add_http_header('Content-Type', 'text/xml; charset=utf-8');

  $output  = "<?xml version=\"1.0\" encoding=\"utf-8\"

\n";

// ...

print $output;
}
?>

I didn't find a single test case for the character set!

BTW Any advice how to setup a test that makes sense? Just testing if the headers are set completely doesn't make sense to me. But it would make sense to check if the encoding of the content matches the charset stated in the headers. But that's far more complex.

mkalkbrenner’s picture

Status: Needs work » Needs review

Any feedback?

mkalkbrenner’s picture

I spent some time on reading through the existing tests and created tests for this issue.

During creating the tests I discovered that not only the XML-RPC server lacks correct definitions of charsets and encodings, but the XML-RPC client has the same issue.

Therefore I extended the patch to fix the XML-RPC client, too.

penyaskito’s picture

Status: Needs review » Needs work

Looks good to me, just some minor issues in coding standards. Once they are fixed, IMHO it is RTBC.
Nice to have better tests for the XML-RPC clients and server :-)

+++ b/core/modules/xmlrpc/lib/Drupal/xmlrpc/Tests/XmlRpcMessagesTest.phpundefined
@@ -62,4 +62,33 @@ protected function testAlterListMethods() {
+    //debug($headers, NULL, TRUE);

Remove debug statements not used. There are two of them.

+++ b/core/modules/xmlrpc/lib/Drupal/xmlrpc/Tests/XmlRpcMessagesTest.phpundefined
@@ -62,4 +62,33 @@ protected function testAlterListMethods() {
+    // we can't use the xmlrpc() function here,
+    // because we have to access the full response of drupal_http_request()

Capital w: "We". And the comment should end with a ".".

Thanks Markus!

mkalkbrenner’s picture

Status: Needs work » Needs review
StatusFileSize
new4.7 KB

fixed minor coding standard issues pointed out by penyaskito.

penyaskito’s picture

Status: Needs review » Reviewed & tested by the community

My comments have been addressed, so catching other's attention.

catch’s picture

Status: Reviewed & tested by the community » Needs work

Patch looks good but I think we can drop the custom assertion. Without that, if the test fails, it'll show you what the expected vs. actual value was anyway.

+    $this->assertIdentical(strpos($headers['Content-Type'], 'text/xml; charset=utf-8'), 0, 'Request Content-Type is "text/xml; charset=utf-8"');
+  }
mkalkbrenner’s picture

Status: Needs work » Needs review
StatusFileSize
new4.78 KB

Ok, I polished the tests.

manumilou’s picture

Version: 8.x-dev » 7.x-dev
StatusFileSize
new630 bytes

Patch backported for 7.x

mkalkbrenner’s picture

Version: 7.x-dev » 8.x-dev
Status: Needs review » Reviewed & tested by the community

Please leave the patch RTBC for D8 first.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

Hey @mkalkbrenner D8 patch in #13 needs a reroll ... no longer applies

$ curl https://drupal.org/files/ajax-number-1964098.pass_.patch | git apply
error: patch failed: core/modules/xmlrpc/xmlrpc.inc:560
mkalkbrenner’s picture

Status: Needs work » Needs review
Issue tags: -Needs backport to D6, -Needs backport to D7
greggles’s picture

Version: 8.0.x-dev » 7.x-dev
Issue summary: View changes

After #1285726-48: Remove XML-RPC moving this to 7.x since it has a patch for that (in #14). It could also go to the contrib xmlrpc first, but I'm not sure.

Status: Needs review » Needs work

The last submitted patch, 14: D7_add_charset_definition_xml_rpc-1774618.patch, failed testing.

mkalkbrenner’s picture

Project: Drupal core » xmlrpc
Version: 7.x-dev » 8.x-1.x-dev
Component: xml-rpc system » Code
fgm’s picture

Status: Needs work » Needs review
StatusFileSize
new4.26 KB

This should now apply, based on the patch in #13, let's see the errors.

Status: Needs review » Needs work

The last submitted patch, 24: 1774618-encoding-24.patch, failed testing.

fgm’s picture

Status: Needs work » Needs review
StatusFileSize
new7.76 KB

It might look like this : not sure this is the exact equivalent : specifically, I wonder whether the first assertIdentical() in XmlRpcMessagesTest::testRequestAndResponseEncodingDefinitions() has any chance of failing, ever.

fgm’s picture

Comment on the first assert in XmlRpcMessagesTest::testRequestAndResponseEncodingDefinitions() was not correct. No other change from #26.

fgm queued 27: 1774618-encoding-27.patch for re-testing.

gábor hojtsy’s picture

Looks nice to me. Apparently test results did not came back, but https://qa.drupal.org/pifr/test/1099603 shows its green.

+++ b/src/XmlRpcTrait.php
@@ -4,11 +4,11 @@
  * Contains XmlRpcControllerBase.php.
  */

Minor: this comment is certainly not true :)

gábor hojtsy’s picture

Status: Needs review » Reviewed & tested by the community
StatusFileSize
new8.75 KB
new409 bytes

Fixed that and another minor whitespace.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 30: 1774618-30.patch, failed testing.

The last submitted patch, 30: 1774618-30.patch, failed testing.

The last submitted patch, 30: 1774618-30.patch, failed testing.

The last submitted patch, 30: 1774618-30.patch, failed testing.

gábor hojtsy’s picture

Status: Needs work » Postponed
gábor hojtsy’s picture

Status: Postponed » Needs work

Well, the guzzle fail is not unrelated. We can fix that here, while the !link fail fix is committed from #2628800: Tests fail on xmlrpc head with invalid !link placeholders..

fgm’s picture

Status: Needs work » Needs review
StatusFileSize
new8.68 KB

Rerolled on current HEAD. One error appears within Guzzle in local tests.

Status: Needs review » Needs work

The last submitted patch, 37: 1774618-encoding-37.patch, failed testing.

The last submitted patch, 37: 1774618-encoding-37.patch, failed testing.

The last submitted patch, 37: 1774618-encoding-37.patch, failed testing.

The last submitted patch, 37: 1774618-encoding-37.patch, failed testing.

fgm’s picture

Status: Needs work » Needs review
StatusFileSize
new9.66 KB
new2.47 KB

One of the fails was just a typo, most (all ?) others related to the PSR-7 switch.

gábor hojtsy’s picture

Status: Needs review » Reviewed & tested by the community

Yay, looks good to me, thanks for the updates. The coverage for setting the charset and for testing it all seems to be adequate. Also getting this in will help with starting the backports to Durpal 7 :)

fgm’s picture

Status: Reviewed & tested by the community » Fixed

Committed to 8.x-1.x HEAD. Thanks all.

  • fgm committed c457149 on 8.x-1.x
    Issue #1774618 by fgm, mkalkbrenner, Gábor Hojtsy, manumilou: charset in...
gábor hojtsy’s picture

Backport Drupal 7 anyone? Should we move this issue back to core or open another one?

The last submitted patch, 30: 1774618-30.patch, failed testing.

The last submitted patch, 37: 1774618-encoding-37.patch, failed testing.

Status: Fixed » Needs work

The last submitted patch, 42: 1774618-encoding-42.patch, failed testing.

fgm’s picture

Project: xmlrpc » Drupal core
Version: 8.x-1.x-dev » 7.x-dev
Component: Code » xml-rpc system
Status: Needs work » Patch (to be ported)

Same topic, same issue, IMO. But not for tonight.

fgm’s picture

Status: Patch (to be ported) » Needs review
StatusFileSize
new44.75 KB

First step : to ease porting and especially later maintenance, test conversion to PSR-4 format. Setting to CNR to trigger bot, but is actually CNW. No actual change besides PSR-4 conversion, so no interdiff.

Status: Needs review » Needs work

The last submitted patch, 51: 1774618-xmlrpc_encoding-51.patch, failed testing.

The last submitted patch, 51: 1774618-xmlrpc_encoding-51.patch, failed testing.

fgm’s picture

Status: Needs work » Needs review
StatusFileSize
new22.14 KB

Oops, wrong patch : included renaming our PHP scripts/run-tests.sh to scripts/run-tests.php.

fgm’s picture

StatusFileSize
new30.41 KB
new22.11 KB

Very rough backport. Not crashing but many fails.

Status: Needs review » Needs work

The last submitted patch, 55: 1774618-xmlrpc_encoding-55.patch, failed testing.

The last submitted patch, 55: 1774618-xmlrpc_encoding-55.patch, failed testing.

fgm’s picture

Status: Needs work » Needs review
StatusFileSize
new38.8 KB
new9.93 KB

Everything should be fixed except the new encoding test being skipped fo rnow.

Status: Needs review » Needs work

The last submitted patch, 58: 1774618-xmlrpc_encoding-57.patch, failed testing.

The last submitted patch, 58: 1774618-xmlrpc_encoding-57.patch, failed testing.

fgm’s picture

Status: Needs work » Needs review
StatusFileSize
new38.66 KB
new966 bytes

Forgot one short-form array... when can we require PHP 5.4 on D7 ?

fgm’s picture

All tests converted and passing locally, plus a pass of coding standards.

fgm’s picture

In case this is not clear, the conversion is finished and awaiting reviews...

gábor hojtsy’s picture

+++ b/includes/xmlrpc.inc
@@ -594,17 +596,25 @@ function _xmlrpc($url, $args, $options = array()) {
-  $options['headers']['Content-Type'] = 'text/xml';
+  $options['headers']['Content-Type'] = 'text/xml; charset=utf-8';

+++ b/includes/xmlrpcs.inc
@@ -124,9 +124,9 @@ function xmlrpc_server_error($error, $message = FALSE) {
 function xmlrpc_server_output($xml) {
-  $xml = '<?xml version="1.0"?>' . "\n" . $xml;
+  $xml = '<?xml version="1.0" encoding="utf-8" ?>' . "\n" . $xml;
   drupal_add_http_header('Content-Length', strlen($xml));
-  drupal_add_http_header('Content-Type', 'text/xml');
+  drupal_add_http_header('Content-Type', 'text/xml; charset=utf-8');
   echo $xml;
   drupal_exit();
 }

These are the key changes, there are a bunch of other misc changes which are bringing the code in line with the Drupal 8 branch I guess. Those do not affect the tests or the issue here, so it would be good to break those out to its own issue IMHO.

For the changes in scope for this patch, I am not sure about the refactoring of the tests to Drupal 8's structure, that is not done in other modules I believe. I can see how it makes backporting fixes easier. Would be great to get committer feedback on it.

fgm’s picture

Basically, there are indeed 4 main changes here :

  • the encoding change which Gábor pointed out, along with its associated test
  • other tests backported from D8 because they had not been backported to D7 when XML-RPC was still in core in early D8 releases
  • a conversion to PSR-4 for tests, to ease ongoing maintenance
  • coding/commenting standards fixes to make all of this consistent with our current level on D8
gábor hojtsy’s picture

Status: Needs review » Needs work

I think those would be important to break into their own issues, since they make reviewing this change hard.

fgm’s picture

Status: Needs work » Postponed

Split into 4 child issues and marked postponed on the child issues. We can reactivate it when they're done.

Status: Postponed » Closed (outdated)

Automatically closed because Drupal 7 security and bugfix support has ended as of 5 January 2025. If the issue verifiably applies to later versions, please reopen with details and update the version.