43 lines
1.5 KiB
Diff
43 lines
1.5 KiB
Diff
|
# Fix crashes/errors due to rtorrent attempting to pass non-utf-8 strings to xmlrpc.
|
||
|
# by jdrexler
|
||
|
Index: rtorrent/src/rpc/xmlrpc.cc
|
||
|
===================================================================
|
||
|
--- rtorrent/src/rpc/xmlrpc.cc (revision 1078)
|
||
|
+++ rtorrent/src/rpc/xmlrpc.cc (working copy)
|
||
|
@@ -371,8 +371,34 @@
|
||
|
#endif
|
||
|
|
||
|
case torrent::Object::TYPE_STRING:
|
||
|
- return xmlrpc_string_new(env, object.as_string().c_str());
|
||
|
+ {
|
||
|
+#ifdef XMLRPC_HAVE_I8
|
||
|
+ // The versions that support I8 do implicit utf-8 validation.
|
||
|
+ xmlrpc_value* result = xmlrpc_string_new(env, object.as_string().c_str());
|
||
|
+#else
|
||
|
+ // In older versions, xmlrpc-c doesn't validate the utf-8 encoding itself.
|
||
|
+ xmlrpc_validate_utf8(env, object.as_string().c_str(), object.as_string().length());
|
||
|
|
||
|
+ xmlrpc_value* result = env->fault_occurred ? NULL : xmlrpc_string_new(env, object.as_string().c_str());
|
||
|
+#endif
|
||
|
+
|
||
|
+ if (env->fault_occurred) {
|
||
|
+ xmlrpc_env_clean(env);
|
||
|
+ xmlrpc_env_init(env);
|
||
|
+
|
||
|
+ const std::string& str = object.as_string();
|
||
|
+ char buffer[str.size() + 1];
|
||
|
+ char* dst = buffer;
|
||
|
+ for (std::string::const_iterator itr = str.begin(); itr != str.end(); ++itr)
|
||
|
+ *dst++ = ((*itr < 0x20 && *itr != '\r' && *itr != '\n' && *itr != '\t') || (*itr & 0x80)) ? '?' : *itr;
|
||
|
+ *dst = 0;
|
||
|
+
|
||
|
+ result = xmlrpc_string_new(env, buffer);
|
||
|
+ }
|
||
|
+
|
||
|
+ return result;
|
||
|
+ }
|
||
|
+
|
||
|
case torrent::Object::TYPE_LIST:
|
||
|
{
|
||
|
xmlrpc_value* result = xmlrpc_array_new(env);
|