summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSadie Powell <sadie@witchery.services>2025-03-10 11:55:33 +0000
committerSadie Powell <sadie@witchery.services>2025-03-10 12:48:13 +0000
commit0ff170c6716b5aa4c5d7a03a83c1513f7d990234 (patch)
treea059f884ef7db0d7c606da919f692fb9123d5586
parentea0d5c4d70990108c00275818e767f0158dab655 (diff)
Add a config option for disabling the i8 XML-RPC extension.
-rw-r--r--data/modules.example.conf4
-rw-r--r--modules/extra/xmlrpc.cpp42
2 files changed, 39 insertions, 7 deletions
diff --git a/data/modules.example.conf b/data/modules.example.conf
index b645693cb..bbe14d5ee 100644
--- a/data/modules.example.conf
+++ b/data/modules.example.conf
@@ -812,8 +812,12 @@ module
* By default Anope will use some extended XML-RPC types. If your XML-RPC
* client can not handle these you will need to disable them.
*
+ * If i8 is disabled a string will be used for values outside of the range
+ * supported by the 32-bit int data type.
+ *
* If nil is disabled an empty struct will be used instead.
*/
+ #enable_i8 = no
#enable_nil = no
}
diff --git a/modules/extra/xmlrpc.cpp b/modules/extra/xmlrpc.cpp
index a4afaa9a3..bc2a0c44a 100644
--- a/modules/extra/xmlrpc.cpp
+++ b/modules/extra/xmlrpc.cpp
@@ -63,6 +63,9 @@ private:
}
public:
+ // Whether we should use the i8 XML-RPC extension.
+ static bool enable_i8;
+
// Whether we should use the nil XML-RPC extension.
static bool enable_nil;
@@ -229,27 +232,51 @@ xmlrpc_value *MyXMLRPCServiceInterface::SerializeElement(xmlrpc_env &env, const
},
[&env, &elem](int64_t i)
{
- elem = xmlrpc_i8_new(&env, i);
+ // XML-RPC does not support 64-bit integers without the use of an
+ // extension.
+ if (!enable_i8 && (i <= INT32_MAX && i >= INT32_MIN))
+ {
+ // We can fit this into a int.
+ elem = xmlrpc_int_new(&env, i);
+ }
+ else if (enable_i8)
+ {
+ // We can fit this into a i8.
+ elem = xmlrpc_i8_new(&env, i);
+ }
+ else
+ {
+ // We need to convert this to a string.
+ auto s = Anope::ToString(i);
+ elem = xmlrpc_string_new_lp(&env, s.length(), s.c_str());
+ }
},
[&env, &elem](uint64_t u)
{
- // XML-RPC does not support unsigned data types.
- if (u > INT64_MAX)
+ // XML-RPC does not support unsigned data types or 64-bit integers
+ // without the use of an extension.
+ if (!enable_i8 && u <= INT32_MAX)
{
- // We need to convert this to a string.
- auto s = Anope::ToString(u);
- elem = xmlrpc_string_new_lp(&env, s.length(), s.c_str());
+ // We can fit this into a int.
+ elem = xmlrpc_int_new(&env, u);
}
- else
+ else if (enable_i8 && u <= INT64_MAX)
{
// We can fit this into a i8.
elem = xmlrpc_i8_new(&env, u);
}
+ else
+ {
+ // We need to convert this to a string.
+ auto s = Anope::ToString(u);
+ elem = xmlrpc_string_new_lp(&env, s.length(), s.c_str());
+ }
},
}, value.Get());
return elem;
}
+bool MyXMLRPCServiceInterface::enable_i8 = true;
bool MyXMLRPCServiceInterface::enable_nil = true;
class ModuleXMLRPC final
@@ -293,6 +320,7 @@ public:
httpref->UnregisterPage(&xmlrpcinterface);
auto &modconf = conf.GetModule(this);
+ MyXMLRPCServiceInterface::enable_i8 = modconf.Get<bool>("enable_i8", "yes");
MyXMLRPCServiceInterface::enable_nil = modconf.Get<bool>("enable_nil", "yes");
this->httpref = ServiceReference<HTTPProvider>("HTTPProvider", modconf.Get<const Anope::string>("server", "httpd/main"));