unicode: Switch compose_second_single to gunichar
[platform/upstream/glib.git] / glib / gvariant-serialiser.c
index 68128e2..5df7fc3 100644 (file)
@@ -13,9 +13,7 @@
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  *
  * Author: Ryan Lortie <desrt@desrt.ca>
  */
  * values is permitted (eg: 0 to 255 is a valid byte).  Special checks
  * need to be performed for booleans (only 0 or 1 allowed), strings
  * (properly nul-terminated) and object paths and signature strings
- * (meeting the DBus specification requirements).
+ * (meeting the D-Bus specification requirements).
  */
 
 /* < private >
  * GVariantSerialised:
  * @type_info: the #GVariantTypeInfo of this value
- * @data: the serialised data of this value, or %NULL
+ * @data: (allow-none): the serialised data of this value, or %NULL
  * @size: the size of this value
  *
  * A structure representing a GVariant in serialised form.  This
@@ -511,7 +509,7 @@ gvs_fixed_sized_array_is_normal (GVariantSerialised value)
  * Variable sized arrays, containing variable-sized elements, must be
  * able to determine the boundaries between the elements.  The items
  * cannot simply be concatenated.  Additionally, we are faced with the
- * fact that non-fixed-sized values do not neccessarily have a size that
+ * fact that non-fixed-sized values do not necessarily have a size that
  * is a multiple of their alignment requirement, so we may need to
  * insert zero-filled padding.
  *
@@ -552,6 +550,7 @@ gvs_fixed_sized_array_is_normal (GVariantSerialised value)
  * normal form and that is the one that the serialiser must produce.
  */
 
+/* bytes may be NULL if (size == 0). */
 static inline gsize
 gvs_read_unaligned_le (guchar *bytes,
                        guint   size)
@@ -563,7 +562,8 @@ gvs_read_unaligned_le (guchar *bytes,
   } tmpvalue;
 
   tmpvalue.integer = 0;
-  memcpy (&tmpvalue.bytes, bytes, size);
+  if (bytes != NULL)
+    memcpy (&tmpvalue.bytes, bytes, size);
 
   return GSIZE_FROM_LE (tmpvalue.integer);
 }
@@ -862,7 +862,7 @@ gvs_tuple_get_child (GVariantSerialised value,
 
   /* tuples are the only (potentially) fixed-sized containers, so the
    * only ones that have to deal with the possibility of having %NULL
-   * data with a non-zero %size if errors occured elsewhere.
+   * data with a non-zero %size if errors occurred elsewhere.
    */
   if G_UNLIKELY (value.data == NULL && value.size != 0)
     {
@@ -918,7 +918,7 @@ gvs_tuple_get_child (GVariantSerialised value,
       child.size = fixed_size;
     }
 
-  else /* G_VARIANT_MEMEBER_ENDING_OFFSET */
+  else /* G_VARIANT_MEMBER_ENDING_OFFSET */
     end = gvs_read_unaligned_le (value.data + value.size -
                                  offset_size * (member_info->i + 2),
                                  offset_size);
@@ -1023,6 +1023,10 @@ gvs_tuple_is_normal (GVariantSerialised value)
   gsize offset;
   gsize i;
 
+  /* as per the comment in gvs_tuple_get_child() */
+  if G_UNLIKELY (value.data == NULL && value.size != 0)
+    return FALSE;
+
   offset_size = gvs_get_offset_size (value.size);
   length = g_variant_type_info_n_members (value.type_info);
   offset_ptr = value.size;
@@ -1300,11 +1304,12 @@ gvs_variant_is_normal (GVariantSerialised value)
 /* < private >
  * g_variant_serialised_n_children:
  * @serialised: a #GVariantSerialised
- * @returns: the number of children
  *
  * For serialised data that represents a container value (maybes,
  * tuples, arrays, variants), determine how many child items are inside
  * that container.
+ *
+ * Returns: the number of children
  */
 gsize
 g_variant_serialised_n_children (GVariantSerialised serialised)
@@ -1323,7 +1328,6 @@ g_variant_serialised_n_children (GVariantSerialised serialised)
  * g_variant_serialised_get_child:
  * @serialised: a #GVariantSerialised
  * @index_: the index of the child to fetch
- * @returns: a #GVariantSerialised for the child
  *
  * Extracts a child from a serialised data representing a container
  * value.
@@ -1338,6 +1342,8 @@ g_variant_serialised_n_children (GVariantSerialised serialised)
  * item of a variable-sized type is being returned.
  *
  * .data is never non-%NULL if size is 0.
+ *
+ * Returns: a #GVariantSerialised for the child
  */
 GVariantSerialised
 g_variant_serialised_get_child (GVariantSerialised serialised,
@@ -1591,21 +1597,30 @@ gboolean
 g_variant_serialiser_is_string (gconstpointer data,
                                 gsize         size)
 {
+  const gchar *expected_end;
   const gchar *end;
 
+  if (size == 0)
+    return FALSE;
+
+  expected_end = ((gchar *) data) + size - 1;
+
+  if (*expected_end != '\0')
+    return FALSE;
+
   g_utf8_validate (data, size, &end);
 
-  return data == end - (size - 1);
+  return end == expected_end;
 }
 
 /* < private >
  * g_variant_serialiser_is_object_path:
- * @data: a possible DBus object path
+ * @data: a possible D-Bus object path
  * @size: the size of @data
  *
  * Performs the checks for being a valid string.
  *
- * Also, ensures that @data is a valid DBus object path, as per the DBus
+ * Also, ensures that @data is a valid DBus object path, as per the D-Bus
  * specification.
  */
 gboolean
@@ -1652,13 +1667,13 @@ g_variant_serialiser_is_object_path (gconstpointer data,
 
 /* < private >
  * g_variant_serialiser_is_signature:
- * @data: a possible DBus signature
+ * @data: a possible D-Bus signature
  * @size: the size of @data
  *
  * Performs the checks for being a valid string.
  *
- * Also, ensures that @data is a valid DBus type signature, as per the
- * DBus specification.
+ * Also, ensures that @data is a valid D-Bus type signature, as per the
+ * D-Bus specification.
  */
 gboolean
 g_variant_serialiser_is_signature (gconstpointer data,