[libsoup/wip/xclaesse/xmlrpc: 5/10] xmlrpc: Add support for nonstandard <i8>



commit 551a954a4aad81432c4c2e97b2df08a77ea4ee37
Author: Xavier Claessens <xavier claessens collabora com>
Date:   Mon Jun 15 17:19:19 2015 -0400

    xmlrpc: Add support for nonstandard <i8>
    
    uint32 can overflow a int32 so it is serialized as <i8>.
    uint64 can overflow a int64 so it still can't be serialized.
    
    For maximum flexibility on the parser side we accept all types
    as long as the value is in range.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=746495

 libsoup/soup-xmlrpc-variant.c |   18 +++++++++++++++---
 tests/xmlrpc-variant-test.c   |   16 ++++++++++++++--
 2 files changed, 29 insertions(+), 5 deletions(-)
---
diff --git a/libsoup/soup-xmlrpc-variant.c b/libsoup/soup-xmlrpc-variant.c
index 4f3756f..86da7dd 100644
--- a/libsoup/soup-xmlrpc-variant.c
+++ b/libsoup/soup-xmlrpc-variant.c
@@ -133,6 +133,14 @@ insert_value (xmlNode *parent, GVariant *value, GError **error)
                snprintf (buf, sizeof (buf), "%d", g_variant_get_int32 (value));
                type_str = "int";
                break;
+       case G_VARIANT_CLASS_UINT32:
+               snprintf (buf, sizeof (buf), "%u", g_variant_get_uint32 (value));
+               type_str = "i8";
+               break;
+       case G_VARIANT_CLASS_INT64:
+               snprintf (buf, sizeof (buf), "%"G_GINT64_FORMAT, g_variant_get_int64 (value));
+               type_str = "i8";
+               break;
        case G_VARIANT_CLASS_DOUBLE:
                g_ascii_dtostr (buf, sizeof (buf), g_variant_get_double (value));
                type_str = "double";
@@ -209,8 +217,6 @@ insert_value (xmlNode *parent, GVariant *value, GError **error)
        }
        case G_VARIANT_CLASS_HANDLE:
        case G_VARIANT_CLASS_MAYBE:
-       case G_VARIANT_CLASS_UINT32:
-       case G_VARIANT_CLASS_INT64:
        case G_VARIANT_CLASS_UINT64:
        default:
                g_set_error (error, SOUP_XMLRPC_ERROR, SOUP_XMLRPC_ERROR_ARGUMENTS,
@@ -243,7 +249,7 @@ fail:
  * @params is a #GVariant tuple representing the method parameters.
  *
  * Limitations that will cause method to return %FALSE and set @error:
- *  - maybes, uint32, int64 and uint64 cannot be serialized.
+ *  - maybes and uint64 cannot be serialized.
  *  - Dictionaries must have string keys.
  *
  * Special cases:
@@ -252,6 +258,7 @@ fail:
  *  - tuples are serialized as &lt;array&gt;
  *  - variants created by soup_xmlrpc_new_datetime() are serialized as
  *    &lt;dateTime.iso8601&gt;
+ *  - uint32 and int64 are serialized as unstandard &lt;i8&gt;
  *
  * If @params is floating, it is consumed.
  *
@@ -877,6 +884,11 @@ parse_value (xmlNode *node, const gchar **signature, GError **error)
                        variant = parse_number (typenode, G_VARIANT_CLASS_INT32, error);
                else
                        variant = parse_number (typenode, class, error);
+       } else if (g_str_equal (typename, "i8")) {
+               if (class == G_VARIANT_CLASS_VARIANT)
+                       variant = parse_number (typenode, G_VARIANT_CLASS_INT64, error);
+               else
+                       variant = parse_number (typenode, class, error);
        } else  if (g_str_equal (typename, "double")) {
                if (class == G_VARIANT_CLASS_VARIANT || class == G_VARIANT_CLASS_DOUBLE) {
                        g_set_error (error, SOUP_XMLRPC_ERROR, SOUP_XMLRPC_ERROR_ARGUMENTS,
diff --git a/tests/xmlrpc-variant-test.c b/tests/xmlrpc-variant-test.c
index ccbbc18..d885f83 100644
--- a/tests/xmlrpc-variant-test.c
+++ b/tests/xmlrpc-variant-test.c
@@ -93,12 +93,15 @@ test_serializer (void)
                "<params>"
                "<param><value><string>&lt;&gt;&amp;</string></value></param>"
                "</params>");
+       verify_serialization (g_variant_new ("(u)", 0),
+               "<params>"
+               "<param><value><i8>0</i8></value></param>"
+               "</params>");
 
        verify_serialization_fail (g_variant_new_parsed ("1"));
        verify_serialization_fail (g_variant_new_parsed ("({1, 2},)"));
        verify_serialization_fail (g_variant_new ("(mi)", NULL));
-       verify_serialization_fail (g_variant_new ("(u)", 0));
-       verify_serialization_fail (g_variant_new ("(t)", G_MAXUINT64));
+       verify_serialization_fail (g_variant_new ("(t)", 0));
 }
 
 static void
@@ -160,6 +163,8 @@ verify_deserialization_fail (const gchar *signature,
 static void
 test_deserializer (void)
 {
+       gchar *tmp;
+
        verify_deserialization (g_variant_new_parsed ("@av []"),
                NULL,
                "<params/>");
@@ -213,6 +218,13 @@ test_deserializer (void)
                "<param><value><int>255</int></value></param>"
                "</params>");
 
+       tmp = g_strdup_printf ("<params>"
+               "<param><value><int>%"G_GUINT64_FORMAT"</int></value></param>"
+               "</params>", G_MAXUINT64);
+       verify_deserialization (g_variant_new ("(t)", G_MAXUINT64),
+               "(t)", tmp);
+       g_free (tmp);
+
        verify_deserialization_fail ("(o)",
                "<params>"
                "<param><value><string>not/a/path</string></value></param>"


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]