Project

General

Profile

Actions

Regression #12816

closed

Namecheap Dynamic DNS responses are not parsed properly

Added by Jim Pingle about 2 years ago. Updated over 1 year ago.

Status:
Resolved
Priority:
Normal
Assignee:
Category:
Dynamic DNS
Target version:
Start date:
Due date:
% Done:

100%

Estimated time:
Plus Target Version:
23.01
Release Notes:
Default
Affected Version:
Affected Architecture:

Description

Namecheap dynamic DNS updates are succeeding on the server side but the dynamic DNS code can't interpret the response. It appears that the encoding is being reported wrong in the response from Namecheap which makes it fail to parse as XML.

The response looks like this now:

<?xml version="1.0" encoding="utf-16"?>
<interface-response>
  <Command>SETDNSHOST</Command>
  <Language>eng</Language>
  <IP>x.x.x.x</IP>
  <ErrCount>0</ErrCount>
  <errors />
  <ResponseCount>0</ResponseCount>
  <responses />
  <Done>true</Done>
  <debug><![CDATA[]]></debug>
</interface-response>

Note that it claims the encoding is UTF-16.

The response array is empty in the code because it is failing to parse due to that error. Trying to run the response through xmllint shows:

parser error : Document labelled UTF-16 but has UTF-8 content

If we drop the first line from the response, that function parses the XML as expected:

diff --git a/src/etc/inc/dyndns.class b/src/etc/inc/dyndns.class
index 8065879cf3..55368b162e 100644
--- a/src/etc/inc/dyndns.class
+++ b/src/etc/inc/dyndns.class
@@ -2412,6 +2412,10 @@
                                case 'namecheap':
                                        $tmp = str_replace("^M", "", $data);
                                        $ncresponse = @xml2array($tmp);
+                                       /* If XML parsing failed, it may be due to mismatched encoding on the response, drop the xml line. */
+                                       if (empty($ncresponse)) {
+                                               $ncresponse = @xml2array(substr($tmp, strpos($tmp, "\n") + 1));
+                                       }
                                        if (preg_match("/internal server error/i", $data)) {
                                                $status = $status_intro . $error_str . gettext("Server side error.");
                                        } else if (preg_match("/request is badly formed/i", $data)) {

I'm not sure if that's the best solution here, though it does work around the problem.


Files

2022-09-10_09-36-54.png (13.2 KB) 2022-09-10_09-36-54.png Lev Prokofev, 09/10/2022 01:37 AM
2022-09-10_09-35-54.png (17.1 KB) 2022-09-10_09-35-54.png Lev Prokofev, 09/10/2022 01:37 AM
Actions

Also available in: Atom PDF