1d012387afef0ba02185ebe27bc6bb15551912e92Havoc Pennington/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
25c486a24e50ef731b8f970060ab10e928cd0e7cdHavoc Pennington/* dbus-marshal-validate.c Validation routines for marshaled data
35c486a24e50ef731b8f970060ab10e928cd0e7cdHavoc Pennington *
45c486a24e50ef731b8f970060ab10e928cd0e7cdHavoc Pennington * Copyright (C) 2005 Red Hat, Inc.
55c486a24e50ef731b8f970060ab10e928cd0e7cdHavoc Pennington *
65c486a24e50ef731b8f970060ab10e928cd0e7cdHavoc Pennington * Licensed under the Academic Free License version 2.1
75c486a24e50ef731b8f970060ab10e928cd0e7cdHavoc Pennington *
85c486a24e50ef731b8f970060ab10e928cd0e7cdHavoc Pennington * This program is free software; you can redistribute it and/or modify
95c486a24e50ef731b8f970060ab10e928cd0e7cdHavoc Pennington * it under the terms of the GNU General Public License as published by
105c486a24e50ef731b8f970060ab10e928cd0e7cdHavoc Pennington * the Free Software Foundation; either version 2 of the License, or
115c486a24e50ef731b8f970060ab10e928cd0e7cdHavoc Pennington * (at your option) any later version.
125c486a24e50ef731b8f970060ab10e928cd0e7cdHavoc Pennington *
135c486a24e50ef731b8f970060ab10e928cd0e7cdHavoc Pennington * This program is distributed in the hope that it will be useful,
145c486a24e50ef731b8f970060ab10e928cd0e7cdHavoc Pennington * but WITHOUT ANY WARRANTY; without even the implied warranty of
155c486a24e50ef731b8f970060ab10e928cd0e7cdHavoc Pennington * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
165c486a24e50ef731b8f970060ab10e928cd0e7cdHavoc Pennington * GNU General Public License for more details.
175c486a24e50ef731b8f970060ab10e928cd0e7cdHavoc Pennington *
185c486a24e50ef731b8f970060ab10e928cd0e7cdHavoc Pennington * You should have received a copy of the GNU General Public License
195c486a24e50ef731b8f970060ab10e928cd0e7cdHavoc Pennington * along with this program; if not, write to the Free Software
205baf2f856a9c6625993234855b07680da1c8916fTobias Mueller * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
215c486a24e50ef731b8f970060ab10e928cd0e7cdHavoc Pennington *
225c486a24e50ef731b8f970060ab10e928cd0e7cdHavoc Pennington */
235c486a24e50ef731b8f970060ab10e928cd0e7cdHavoc Pennington
24dbecdeabb20e0ce11121819c63373f0afba57c58Marcus Brinkmann#include <config.h>
255c486a24e50ef731b8f970060ab10e928cd0e7cdHavoc Pennington#include "dbus-internals.h"
265c486a24e50ef731b8f970060ab10e928cd0e7cdHavoc Pennington#include "dbus-marshal-validate.h"
279c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington#include "dbus-marshal-recursive.h"
28fddbc09c4a9125fcb168fb31ff300d4132919ea6Havoc Pennington#include "dbus-marshal-basic.h"
2954a2e9f7961b4b8afff94bb0c5b756f986965be6Colin Walters#include "dbus-signature.h"
30fddbc09c4a9125fcb168fb31ff300d4132919ea6Havoc Pennington#include "dbus-string.h"
315c486a24e50ef731b8f970060ab10e928cd0e7cdHavoc Pennington
325c486a24e50ef731b8f970060ab10e928cd0e7cdHavoc Pennington/**
335c486a24e50ef731b8f970060ab10e928cd0e7cdHavoc Pennington * @addtogroup DBusMarshal
345c486a24e50ef731b8f970060ab10e928cd0e7cdHavoc Pennington *
355c486a24e50ef731b8f970060ab10e928cd0e7cdHavoc Pennington * @{
365c486a24e50ef731b8f970060ab10e928cd0e7cdHavoc Pennington */
375c486a24e50ef731b8f970060ab10e928cd0e7cdHavoc Pennington
389c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington/**
399c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * Verifies that the range of type_str from type_pos to type_end is a
409c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * valid signature.  If this function returns #TRUE, it will be safe
419c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * to iterate over the signature with a types-only #DBusTypeReader.
429c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * The range passed in should NOT include the terminating
439c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * nul/DBUS_TYPE_INVALID.
449c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington *
459c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * @param type_str the string
469c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * @param type_pos where the typecodes start
479c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * @param len length of typecodes
489c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * @returns #DBUS_VALID if valid, reason why invalid otherwise
499c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington */
509c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc PenningtonDBusValidity
519c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington_dbus_validate_signature_with_reason (const DBusString *type_str,
529c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                                      int               type_pos,
539c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                                      int               len)
549c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington{
559c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  const unsigned char *p;
569c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  const unsigned char *end;
579c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  int last;
589c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  int struct_depth;
599c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  int array_depth;
60c7816d45e82ba8dd7e1e969c2cb6c3a27577cf68Havoc Pennington  int dict_entry_depth;
615e389fdf499c39926c61b47fcafb5e71291ce1a2John (J  DBusValidity result;
625e389fdf499c39926c61b47fcafb5e71291ce1a2John (J
635e389fdf499c39926c61b47fcafb5e71291ce1a2John (J  int element_count;
645e389fdf499c39926c61b47fcafb5e71291ce1a2John (J  DBusList *element_count_stack;
655e389fdf499c39926c61b47fcafb5e71291ce1a2John (J
665e389fdf499c39926c61b47fcafb5e71291ce1a2John (J  result = DBUS_VALID;
675e389fdf499c39926c61b47fcafb5e71291ce1a2John (J  element_count_stack = NULL;
685e389fdf499c39926c61b47fcafb5e71291ce1a2John (J
695e389fdf499c39926c61b47fcafb5e71291ce1a2John (J  if (!_dbus_list_append (&element_count_stack, _DBUS_INT_TO_POINTER (0)))
705e389fdf499c39926c61b47fcafb5e71291ce1a2John (J    {
715e389fdf499c39926c61b47fcafb5e71291ce1a2John (J      result = DBUS_VALIDITY_UNKNOWN_OOM_ERROR;
725e389fdf499c39926c61b47fcafb5e71291ce1a2John (J      goto out;
735e389fdf499c39926c61b47fcafb5e71291ce1a2John (J    }
749c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
759c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  _dbus_assert (type_str != NULL);
763ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington  _dbus_assert (type_pos < _DBUS_INT32_MAX - len);
779c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  _dbus_assert (len >= 0);
789c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  _dbus_assert (type_pos >= 0);
799c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
809c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  if (len > DBUS_MAXIMUM_SIGNATURE_LENGTH)
815e389fdf499c39926c61b47fcafb5e71291ce1a2John (J    {
825e389fdf499c39926c61b47fcafb5e71291ce1a2John (J      result = DBUS_INVALID_SIGNATURE_TOO_LONG;
835e389fdf499c39926c61b47fcafb5e71291ce1a2John (J      goto out;
845e389fdf499c39926c61b47fcafb5e71291ce1a2John (J    }
859c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
869c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  p = _dbus_string_get_const_data_len (type_str, type_pos, 0);
875e389fdf499c39926c61b47fcafb5e71291ce1a2John (J
889c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  end = _dbus_string_get_const_data_len (type_str, type_pos + len, 0);
899c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  struct_depth = 0;
909c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  array_depth = 0;
91c7816d45e82ba8dd7e1e969c2cb6c3a27577cf68Havoc Pennington  dict_entry_depth = 0;
929c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  last = DBUS_TYPE_INVALID;
939c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
949c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  while (p != end)
959c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington    {
969c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington      switch (*p)
979c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        {
989c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        case DBUS_TYPE_BYTE:
999c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        case DBUS_TYPE_BOOLEAN:
1003ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington        case DBUS_TYPE_INT16:
1013ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington        case DBUS_TYPE_UINT16:
1029c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        case DBUS_TYPE_INT32:
1039c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        case DBUS_TYPE_UINT32:
104ba7daa606cf20ff3b5e992907f380a425feaef01Lennart Poettering        case DBUS_TYPE_UNIX_FD:
1059c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        case DBUS_TYPE_INT64:
1069c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        case DBUS_TYPE_UINT64:
1079c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        case DBUS_TYPE_DOUBLE:
1089c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        case DBUS_TYPE_STRING:
1099c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        case DBUS_TYPE_OBJECT_PATH:
1109c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        case DBUS_TYPE_SIGNATURE:
1119c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        case DBUS_TYPE_VARIANT:
1129c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          break;
1139c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
1149c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        case DBUS_TYPE_ARRAY:
1159c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          array_depth += 1;
1169c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          if (array_depth > DBUS_MAXIMUM_TYPE_RECURSION_DEPTH)
1175e389fdf499c39926c61b47fcafb5e71291ce1a2John (J            {
1185e389fdf499c39926c61b47fcafb5e71291ce1a2John (J              result = DBUS_INVALID_EXCEEDED_MAXIMUM_ARRAY_RECURSION;
1195e389fdf499c39926c61b47fcafb5e71291ce1a2John (J              goto out;
1205e389fdf499c39926c61b47fcafb5e71291ce1a2John (J            }
1219c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          break;
1229c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
1239c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        case DBUS_STRUCT_BEGIN_CHAR:
1249c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          struct_depth += 1;
1259c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
1269c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          if (struct_depth > DBUS_MAXIMUM_TYPE_RECURSION_DEPTH)
1275e389fdf499c39926c61b47fcafb5e71291ce1a2John (J            {
1285e389fdf499c39926c61b47fcafb5e71291ce1a2John (J              result = DBUS_INVALID_EXCEEDED_MAXIMUM_STRUCT_RECURSION;
1295e389fdf499c39926c61b47fcafb5e71291ce1a2John (J              goto out;
1305e389fdf499c39926c61b47fcafb5e71291ce1a2John (J            }
1315e389fdf499c39926c61b47fcafb5e71291ce1a2John (J
1325e389fdf499c39926c61b47fcafb5e71291ce1a2John (J          if (!_dbus_list_append (&element_count_stack,
1335e389fdf499c39926c61b47fcafb5e71291ce1a2John (J                             _DBUS_INT_TO_POINTER (0)))
1345e389fdf499c39926c61b47fcafb5e71291ce1a2John (J            {
1355e389fdf499c39926c61b47fcafb5e71291ce1a2John (J              result = DBUS_VALIDITY_UNKNOWN_OOM_ERROR;
1365e389fdf499c39926c61b47fcafb5e71291ce1a2John (J              goto out;
1375e389fdf499c39926c61b47fcafb5e71291ce1a2John (J            }
1385e389fdf499c39926c61b47fcafb5e71291ce1a2John (J
1399c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          break;
1409c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
1419c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        case DBUS_STRUCT_END_CHAR:
1429c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          if (struct_depth == 0)
1435e389fdf499c39926c61b47fcafb5e71291ce1a2John (J            {
1445e389fdf499c39926c61b47fcafb5e71291ce1a2John (J              result = DBUS_INVALID_STRUCT_ENDED_BUT_NOT_STARTED;
1455e389fdf499c39926c61b47fcafb5e71291ce1a2John (J              goto out;
1465e389fdf499c39926c61b47fcafb5e71291ce1a2John (J            }
1479c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
1489c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          if (last == DBUS_STRUCT_BEGIN_CHAR)
1495e389fdf499c39926c61b47fcafb5e71291ce1a2John (J            {
1505e389fdf499c39926c61b47fcafb5e71291ce1a2John (J              result = DBUS_INVALID_STRUCT_HAS_NO_FIELDS;
1515e389fdf499c39926c61b47fcafb5e71291ce1a2John (J              goto out;
1525e389fdf499c39926c61b47fcafb5e71291ce1a2John (J            }
1535e389fdf499c39926c61b47fcafb5e71291ce1a2John (J
1545e389fdf499c39926c61b47fcafb5e71291ce1a2John (J          _dbus_list_pop_last (&element_count_stack);
1559c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
1569c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          struct_depth -= 1;
1579c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          break;
1589c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
159c7816d45e82ba8dd7e1e969c2cb6c3a27577cf68Havoc Pennington        case DBUS_DICT_ENTRY_BEGIN_CHAR:
160c7816d45e82ba8dd7e1e969c2cb6c3a27577cf68Havoc Pennington          if (last != DBUS_TYPE_ARRAY)
1615e389fdf499c39926c61b47fcafb5e71291ce1a2John (J            {
1625e389fdf499c39926c61b47fcafb5e71291ce1a2John (J              result = DBUS_INVALID_DICT_ENTRY_NOT_INSIDE_ARRAY;
1635e389fdf499c39926c61b47fcafb5e71291ce1a2John (J              goto out;
1645e389fdf499c39926c61b47fcafb5e71291ce1a2John (J            }
1655e389fdf499c39926c61b47fcafb5e71291ce1a2John (J
166c7816d45e82ba8dd7e1e969c2cb6c3a27577cf68Havoc Pennington          dict_entry_depth += 1;
167c7816d45e82ba8dd7e1e969c2cb6c3a27577cf68Havoc Pennington
168c7816d45e82ba8dd7e1e969c2cb6c3a27577cf68Havoc Pennington          if (dict_entry_depth > DBUS_MAXIMUM_TYPE_RECURSION_DEPTH)
1695e389fdf499c39926c61b47fcafb5e71291ce1a2John (J            {
1705e389fdf499c39926c61b47fcafb5e71291ce1a2John (J              result = DBUS_INVALID_EXCEEDED_MAXIMUM_DICT_ENTRY_RECURSION;
1715e389fdf499c39926c61b47fcafb5e71291ce1a2John (J              goto out;
1725e389fdf499c39926c61b47fcafb5e71291ce1a2John (J            }
1735e389fdf499c39926c61b47fcafb5e71291ce1a2John (J
1745e389fdf499c39926c61b47fcafb5e71291ce1a2John (J          if (!_dbus_list_append (&element_count_stack,
1755e389fdf499c39926c61b47fcafb5e71291ce1a2John (J                             _DBUS_INT_TO_POINTER (0)))
1765e389fdf499c39926c61b47fcafb5e71291ce1a2John (J            {
1775e389fdf499c39926c61b47fcafb5e71291ce1a2John (J              result = DBUS_VALIDITY_UNKNOWN_OOM_ERROR;
1785e389fdf499c39926c61b47fcafb5e71291ce1a2John (J              goto out;
1795e389fdf499c39926c61b47fcafb5e71291ce1a2John (J            }
1805e389fdf499c39926c61b47fcafb5e71291ce1a2John (J
181c7816d45e82ba8dd7e1e969c2cb6c3a27577cf68Havoc Pennington          break;
182c7816d45e82ba8dd7e1e969c2cb6c3a27577cf68Havoc Pennington
183c7816d45e82ba8dd7e1e969c2cb6c3a27577cf68Havoc Pennington        case DBUS_DICT_ENTRY_END_CHAR:
184c7816d45e82ba8dd7e1e969c2cb6c3a27577cf68Havoc Pennington          if (dict_entry_depth == 0)
1855e389fdf499c39926c61b47fcafb5e71291ce1a2John (J            {
1865e389fdf499c39926c61b47fcafb5e71291ce1a2John (J              result = DBUS_INVALID_DICT_ENTRY_ENDED_BUT_NOT_STARTED;
1875e389fdf499c39926c61b47fcafb5e71291ce1a2John (J              goto out;
1885e389fdf499c39926c61b47fcafb5e71291ce1a2John (J            }
1895e389fdf499c39926c61b47fcafb5e71291ce1a2John (J
190c7816d45e82ba8dd7e1e969c2cb6c3a27577cf68Havoc Pennington          dict_entry_depth -= 1;
1915e389fdf499c39926c61b47fcafb5e71291ce1a2John (J
1925e389fdf499c39926c61b47fcafb5e71291ce1a2John (J          element_count =
1935e389fdf499c39926c61b47fcafb5e71291ce1a2John (J            _DBUS_POINTER_TO_INT (_dbus_list_pop_last (&element_count_stack));
1945e389fdf499c39926c61b47fcafb5e71291ce1a2John (J
1955e389fdf499c39926c61b47fcafb5e71291ce1a2John (J          if (element_count != 2)
1965e389fdf499c39926c61b47fcafb5e71291ce1a2John (J            {
1975e389fdf499c39926c61b47fcafb5e71291ce1a2John (J              if (element_count == 0)
1985e389fdf499c39926c61b47fcafb5e71291ce1a2John (J                result = DBUS_INVALID_DICT_ENTRY_HAS_NO_FIELDS;
1995e389fdf499c39926c61b47fcafb5e71291ce1a2John (J              else if (element_count == 1)
2005e389fdf499c39926c61b47fcafb5e71291ce1a2John (J                result = DBUS_INVALID_DICT_ENTRY_HAS_ONLY_ONE_FIELD;
2015e389fdf499c39926c61b47fcafb5e71291ce1a2John (J              else
2025e389fdf499c39926c61b47fcafb5e71291ce1a2John (J                result = DBUS_INVALID_DICT_ENTRY_HAS_TOO_MANY_FIELDS;
2035e389fdf499c39926c61b47fcafb5e71291ce1a2John (J
2045e389fdf499c39926c61b47fcafb5e71291ce1a2John (J              goto out;
2055e389fdf499c39926c61b47fcafb5e71291ce1a2John (J            }
206c7816d45e82ba8dd7e1e969c2cb6c3a27577cf68Havoc Pennington          break;
207c7816d45e82ba8dd7e1e969c2cb6c3a27577cf68Havoc Pennington
208c7816d45e82ba8dd7e1e969c2cb6c3a27577cf68Havoc Pennington        case DBUS_TYPE_STRUCT:     /* doesn't appear in signatures */
209c7816d45e82ba8dd7e1e969c2cb6c3a27577cf68Havoc Pennington        case DBUS_TYPE_DICT_ENTRY: /* ditto */
2109c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        default:
2115e389fdf499c39926c61b47fcafb5e71291ce1a2John (J          result = DBUS_INVALID_UNKNOWN_TYPECODE;
2125e389fdf499c39926c61b47fcafb5e71291ce1a2John (J	  goto out;
2139c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        }
2149c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
2155e389fdf499c39926c61b47fcafb5e71291ce1a2John (J      if (*p != DBUS_TYPE_ARRAY &&
2165e389fdf499c39926c61b47fcafb5e71291ce1a2John (J          *p != DBUS_DICT_ENTRY_BEGIN_CHAR &&
2175e389fdf499c39926c61b47fcafb5e71291ce1a2John (J	  *p != DBUS_STRUCT_BEGIN_CHAR)
2185e389fdf499c39926c61b47fcafb5e71291ce1a2John (J        {
2195e389fdf499c39926c61b47fcafb5e71291ce1a2John (J          element_count =
2205e389fdf499c39926c61b47fcafb5e71291ce1a2John (J            _DBUS_POINTER_TO_INT (_dbus_list_pop_last (&element_count_stack));
2215e389fdf499c39926c61b47fcafb5e71291ce1a2John (J
2225e389fdf499c39926c61b47fcafb5e71291ce1a2John (J          ++element_count;
2235e389fdf499c39926c61b47fcafb5e71291ce1a2John (J
2245e389fdf499c39926c61b47fcafb5e71291ce1a2John (J          if (!_dbus_list_append (&element_count_stack,
2255e389fdf499c39926c61b47fcafb5e71291ce1a2John (J                             _DBUS_INT_TO_POINTER (element_count)))
2265e389fdf499c39926c61b47fcafb5e71291ce1a2John (J            {
2275e389fdf499c39926c61b47fcafb5e71291ce1a2John (J              result = DBUS_VALIDITY_UNKNOWN_OOM_ERROR;
2285e389fdf499c39926c61b47fcafb5e71291ce1a2John (J              goto out;
2295e389fdf499c39926c61b47fcafb5e71291ce1a2John (J            }
2305e389fdf499c39926c61b47fcafb5e71291ce1a2John (J        }
2315e389fdf499c39926c61b47fcafb5e71291ce1a2John (J
2320e53d4eed36f378e99802e516fbb0d1355641902Havoc Pennington      if (array_depth > 0)
2330e53d4eed36f378e99802e516fbb0d1355641902Havoc Pennington        {
2345e389fdf499c39926c61b47fcafb5e71291ce1a2John (J          if (*p == DBUS_TYPE_ARRAY && p != end)
2355e389fdf499c39926c61b47fcafb5e71291ce1a2John (J            {
2365e389fdf499c39926c61b47fcafb5e71291ce1a2John (J	       const char *p1;
2375e389fdf499c39926c61b47fcafb5e71291ce1a2John (J	       p1 = p + 1;
2385e389fdf499c39926c61b47fcafb5e71291ce1a2John (J               if (*p1 == DBUS_STRUCT_END_CHAR ||
2395e389fdf499c39926c61b47fcafb5e71291ce1a2John (J                   *p1 == DBUS_DICT_ENTRY_END_CHAR)
2405e389fdf499c39926c61b47fcafb5e71291ce1a2John (J                 {
2415e389fdf499c39926c61b47fcafb5e71291ce1a2John (J                   result = DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE;
2425e389fdf499c39926c61b47fcafb5e71291ce1a2John (J                   goto out;
2435e389fdf499c39926c61b47fcafb5e71291ce1a2John (J                 }
2445e389fdf499c39926c61b47fcafb5e71291ce1a2John (J            }
2450e53d4eed36f378e99802e516fbb0d1355641902Havoc Pennington          else
2465e389fdf499c39926c61b47fcafb5e71291ce1a2John (J	    {
2475e389fdf499c39926c61b47fcafb5e71291ce1a2John (J              array_depth = 0;
2485e389fdf499c39926c61b47fcafb5e71291ce1a2John (J	    }
2490e53d4eed36f378e99802e516fbb0d1355641902Havoc Pennington        }
2509c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
251e8f8c1c5a2bddfbf43c168323c9c9fd78f51a643Colin Walters      if (last == DBUS_DICT_ENTRY_BEGIN_CHAR)
2525e389fdf499c39926c61b47fcafb5e71291ce1a2John (J        {
253e8f8c1c5a2bddfbf43c168323c9c9fd78f51a643Colin Walters          if (!(_dbus_type_is_valid (*p) && dbus_type_is_basic (*p)))
254e8f8c1c5a2bddfbf43c168323c9c9fd78f51a643Colin Walters            {
255e8f8c1c5a2bddfbf43c168323c9c9fd78f51a643Colin Walters              result = DBUS_INVALID_DICT_KEY_MUST_BE_BASIC_TYPE;
256e8f8c1c5a2bddfbf43c168323c9c9fd78f51a643Colin Walters              goto out;
257e8f8c1c5a2bddfbf43c168323c9c9fd78f51a643Colin Walters            }
2585e389fdf499c39926c61b47fcafb5e71291ce1a2John (J        }
259e8f8c1c5a2bddfbf43c168323c9c9fd78f51a643Colin Walters
2609c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington      last = *p;
2619c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington      ++p;
2629c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington    }
2639c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
2649c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
2655e389fdf499c39926c61b47fcafb5e71291ce1a2John (J  if (array_depth > 0)
2665e389fdf499c39926c61b47fcafb5e71291ce1a2John (J    {
2675e389fdf499c39926c61b47fcafb5e71291ce1a2John (J      result = DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE;
2685e389fdf499c39926c61b47fcafb5e71291ce1a2John (J      goto out;
2695e389fdf499c39926c61b47fcafb5e71291ce1a2John (J    }
2705e389fdf499c39926c61b47fcafb5e71291ce1a2John (J
2719c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  if (struct_depth > 0)
2725e389fdf499c39926c61b47fcafb5e71291ce1a2John (J    {
2735e389fdf499c39926c61b47fcafb5e71291ce1a2John (J       result = DBUS_INVALID_STRUCT_STARTED_BUT_NOT_ENDED;
2745e389fdf499c39926c61b47fcafb5e71291ce1a2John (J       goto out;
2755e389fdf499c39926c61b47fcafb5e71291ce1a2John (J    }
2765e389fdf499c39926c61b47fcafb5e71291ce1a2John (J
277c7816d45e82ba8dd7e1e969c2cb6c3a27577cf68Havoc Pennington  if (dict_entry_depth > 0)
2785e389fdf499c39926c61b47fcafb5e71291ce1a2John (J    {
2795e389fdf499c39926c61b47fcafb5e71291ce1a2John (J      result =  DBUS_INVALID_DICT_ENTRY_STARTED_BUT_NOT_ENDED;
2805e389fdf499c39926c61b47fcafb5e71291ce1a2John (J      goto out;
2815e389fdf499c39926c61b47fcafb5e71291ce1a2John (J    }
2825e389fdf499c39926c61b47fcafb5e71291ce1a2John (J
2830e53d4eed36f378e99802e516fbb0d1355641902Havoc Pennington  _dbus_assert (last != DBUS_TYPE_ARRAY);
2840e53d4eed36f378e99802e516fbb0d1355641902Havoc Pennington  _dbus_assert (last != DBUS_STRUCT_BEGIN_CHAR);
2850e53d4eed36f378e99802e516fbb0d1355641902Havoc Pennington  _dbus_assert (last != DBUS_DICT_ENTRY_BEGIN_CHAR);
2865e389fdf499c39926c61b47fcafb5e71291ce1a2John (J
2875e389fdf499c39926c61b47fcafb5e71291ce1a2John (J  result = DBUS_VALID;
2885e389fdf499c39926c61b47fcafb5e71291ce1a2John (J
2895e389fdf499c39926c61b47fcafb5e71291ce1a2John (Jout:
2905e389fdf499c39926c61b47fcafb5e71291ce1a2John (J  _dbus_list_clear (&element_count_stack);
2915e389fdf499c39926c61b47fcafb5e71291ce1a2John (J  return result;
2929c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington}
2939c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
294c11401949f29a97414887a01f0d3e6e8fe60ba40Havoc Pennington/* note: this function is also used to validate the header's values,
295c11401949f29a97414887a01f0d3e6e8fe60ba40Havoc Pennington * since the header is a valid body with a particular signature.
296c11401949f29a97414887a01f0d3e6e8fe60ba40Havoc Pennington */
2979c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Penningtonstatic DBusValidity
2989c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Penningtonvalidate_body_helper (DBusTypeReader       *reader,
2999c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                      int                   byte_order,
3009c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                      dbus_bool_t           walk_reader_to_end,
301c11401949f29a97414887a01f0d3e6e8fe60ba40Havoc Pennington                      int                   total_depth,
3029c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                      const unsigned char  *p,
3039c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                      const unsigned char  *end,
3049c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                      const unsigned char **new_p)
3059c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington{
3069c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  int current_type;
3079c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
308c11401949f29a97414887a01f0d3e6e8fe60ba40Havoc Pennington  /* The spec allows arrays and structs to each nest 32, for total
309c11401949f29a97414887a01f0d3e6e8fe60ba40Havoc Pennington   * nesting of 2*32. We want to impose the same limit on "dynamic"
310c11401949f29a97414887a01f0d3e6e8fe60ba40Havoc Pennington   * value nesting (not visible in the signature) which is introduced
311c11401949f29a97414887a01f0d3e6e8fe60ba40Havoc Pennington   * by DBUS_TYPE_VARIANT.
312c11401949f29a97414887a01f0d3e6e8fe60ba40Havoc Pennington   */
313c11401949f29a97414887a01f0d3e6e8fe60ba40Havoc Pennington  if (total_depth > (DBUS_MAXIMUM_TYPE_RECURSION_DEPTH * 2))
314c11401949f29a97414887a01f0d3e6e8fe60ba40Havoc Pennington    {
315c11401949f29a97414887a01f0d3e6e8fe60ba40Havoc Pennington      return DBUS_INVALID_NESTED_TOO_DEEPLY;
316c11401949f29a97414887a01f0d3e6e8fe60ba40Havoc Pennington    }
317c11401949f29a97414887a01f0d3e6e8fe60ba40Havoc Pennington
3189c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  while ((current_type = _dbus_type_reader_get_current_type (reader)) != DBUS_TYPE_INVALID)
3199c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington    {
3209c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington      const unsigned char *a;
3219c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington      int alignment;
3229c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
32398ad8a8ec6626f7f5c78915b6bdf2be688b4839fHavoc Pennington#if 0
3249c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington      _dbus_verbose ("   validating value of type %s type reader %p type_pos %d p %p end %p %d remain\n",
3259c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                     _dbus_type_to_string (current_type), reader, reader->type_pos, p, end,
3269c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                     (int) (end - p));
32798ad8a8ec6626f7f5c78915b6bdf2be688b4839fHavoc Pennington#endif
3289c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
3299c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington      /* Guarantee that p has one byte to look at */
3309c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington      if (p == end)
3319c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        return DBUS_INVALID_NOT_ENOUGH_DATA;
3329c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
3339c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington      switch (current_type)
3349c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        {
3359c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        case DBUS_TYPE_BYTE:
3369c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          ++p;
3379c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          break;
338ba7daa606cf20ff3b5e992907f380a425feaef01Lennart Poettering
3399c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        case DBUS_TYPE_BOOLEAN:
3403ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington        case DBUS_TYPE_INT16:
3413ed9db546e1143bc9aa2d83a6f423fdd81227352Havoc Pennington        case DBUS_TYPE_UINT16:
3429c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        case DBUS_TYPE_INT32:
3439c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        case DBUS_TYPE_UINT32:
344ba7daa606cf20ff3b5e992907f380a425feaef01Lennart Poettering        case DBUS_TYPE_UNIX_FD:
3459c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        case DBUS_TYPE_INT64:
3469c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        case DBUS_TYPE_UINT64:
3479c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        case DBUS_TYPE_DOUBLE:
3489c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          alignment = _dbus_type_get_alignment (current_type);
3499c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          a = _DBUS_ALIGN_ADDRESS (p, alignment);
3509c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          if (a >= end)
3519c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            return DBUS_INVALID_NOT_ENOUGH_DATA;
3529c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          while (p != a)
3539c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            {
3549c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington              if (*p != '\0')
3559c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                return DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
3569c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington              ++p;
3579c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            }
35862e465339a306fa564b69935da494dad6e1b474aHavoc Pennington
35962e465339a306fa564b69935da494dad6e1b474aHavoc Pennington          if (current_type == DBUS_TYPE_BOOLEAN)
36062e465339a306fa564b69935da494dad6e1b474aHavoc Pennington            {
36162e465339a306fa564b69935da494dad6e1b474aHavoc Pennington              dbus_uint32_t v = _dbus_unpack_uint32 (byte_order,
36262e465339a306fa564b69935da494dad6e1b474aHavoc Pennington                                                     p);
36362e465339a306fa564b69935da494dad6e1b474aHavoc Pennington              if (!(v == 0 || v == 1))
36462e465339a306fa564b69935da494dad6e1b474aHavoc Pennington                return DBUS_INVALID_BOOLEAN_NOT_ZERO_OR_ONE;
36562e465339a306fa564b69935da494dad6e1b474aHavoc Pennington            }
36662e465339a306fa564b69935da494dad6e1b474aHavoc Pennington
3679c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          p += alignment;
3689c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          break;
3699c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
3709c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        case DBUS_TYPE_ARRAY:
3719c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        case DBUS_TYPE_STRING:
3729c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        case DBUS_TYPE_OBJECT_PATH:
3739c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          {
3749c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            dbus_uint32_t claimed_len;
3759c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
3769c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            a = _DBUS_ALIGN_ADDRESS (p, 4);
37772c433f80ba964f03688b61ff754b1c93d0fb4adHavoc Pennington            if (a + 4 > end)
3789c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington              return DBUS_INVALID_NOT_ENOUGH_DATA;
3799c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            while (p != a)
3809c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington              {
3819c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                if (*p != '\0')
3829c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                  return DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
3839c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                ++p;
3849c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington              }
3859c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
3869c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            claimed_len = _dbus_unpack_uint32 (byte_order, p);
3879c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            p += 4;
3889c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
38972c433f80ba964f03688b61ff754b1c93d0fb4adHavoc Pennington            /* p may now be == end */
39072c433f80ba964f03688b61ff754b1c93d0fb4adHavoc Pennington            _dbus_assert (p <= end);
391e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting
3929c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            if (current_type == DBUS_TYPE_ARRAY)
3939c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington              {
39431988af4089f3793940417535f8eabaae1ac26c8Havoc Pennington                int array_elem_type = _dbus_type_reader_get_element_type (reader);
395e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting
396e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                if (!_dbus_type_is_valid (array_elem_type))
397e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                  {
398e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                    return DBUS_INVALID_UNKNOWN_TYPECODE;
399e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                  }
400e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting
4019c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                alignment = _dbus_type_get_alignment (array_elem_type);
402e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting
403e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                a = _DBUS_ALIGN_ADDRESS (p, alignment);
404e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting
405e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                /* a may now be == end */
406e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                if (a > end)
407e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                  return DBUS_INVALID_NOT_ENOUGH_DATA;
408e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting
409e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                while (p != a)
410e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                  {
411e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                    if (*p != '\0')
412e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                      return DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
413e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                    ++p;
414e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                  }
4159c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington              }
4169c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
4179c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            if (claimed_len > (unsigned long) (end - p))
41896a47516321dea8c08e1ab15ac0102ce3c3ae3f1Havoc Pennington              return DBUS_INVALID_LENGTH_OUT_OF_BOUNDS;
4199c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
4209c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            if (current_type == DBUS_TYPE_OBJECT_PATH)
4219c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington              {
4229c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                DBusString str;
4239c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                _dbus_string_init_const_len (&str, p, claimed_len);
4249c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                if (!_dbus_validate_path (&str, 0,
4259c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                                          _dbus_string_get_length (&str)))
4269c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                  return DBUS_INVALID_BAD_PATH;
4279c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
4289c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                p += claimed_len;
4299c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington              }
4309c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            else if (current_type == DBUS_TYPE_STRING)
4319c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington              {
4329c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                DBusString str;
4339c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                _dbus_string_init_const_len (&str, p, claimed_len);
4349c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                if (!_dbus_string_validate_utf8 (&str, 0,
4359c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                                                 _dbus_string_get_length (&str)))
4369c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                  return DBUS_INVALID_BAD_UTF8_IN_STRING;
4379c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
4389c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                p += claimed_len;
4399c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington              }
4409c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            else if (current_type == DBUS_TYPE_ARRAY && claimed_len > 0)
4419c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington              {
4429c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                DBusTypeReader sub;
4439c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                DBusValidity validity;
4449c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                const unsigned char *array_end;
445e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                int array_elem_type;
4469c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
44796a47516321dea8c08e1ab15ac0102ce3c3ae3f1Havoc Pennington                if (claimed_len > DBUS_MAXIMUM_ARRAY_LENGTH)
44896a47516321dea8c08e1ab15ac0102ce3c3ae3f1Havoc Pennington                  return DBUS_INVALID_ARRAY_LENGTH_EXCEEDS_MAXIMUM;
44996a47516321dea8c08e1ab15ac0102ce3c3ae3f1Havoc Pennington
4509c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                /* Remember that the reader is types only, so we can't
4519c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                 * use it to iterate over elements. It stays the same
4529c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                 * for all elements.
4539c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                 */
4549c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                _dbus_type_reader_recurse (reader, &sub);
4559c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
4569c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                array_end = p + claimed_len;
4579c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
458e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                array_elem_type = _dbus_type_reader_get_element_type (reader);
459e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting
460e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                /* avoid recursive call to validate_body_helper if this is an array
461e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                 * of fixed-size elements
462e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                 */
463e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                if (dbus_type_is_fixed (array_elem_type))
464e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                  {
465e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                    /* bools need to be handled differently, because they can
466e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                     * have an invalid value
467e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                     */
468e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                    if (array_elem_type == DBUS_TYPE_BOOLEAN)
469e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                      {
470e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                        dbus_uint32_t v;
471e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                        alignment = _dbus_type_get_alignment (array_elem_type);
472e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting
473e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                        while (p < array_end)
474e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                          {
475e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                            v = _dbus_unpack_uint32 (byte_order, p);
476e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting
477e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                            if (!(v == 0 || v == 1))
478e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                              return DBUS_INVALID_BOOLEAN_NOT_ZERO_OR_ONE;
479e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting
480e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                            p += alignment;
481e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                          }
482e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                      }
483e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting
484e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                    else
485e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                      {
486e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                        p = array_end;
487e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                      }
488e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                  }
489e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting
490e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                else
4919c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                  {
492e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                    while (p < array_end)
493e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                      {
494c11401949f29a97414887a01f0d3e6e8fe60ba40Havoc Pennington                        validity = validate_body_helper (&sub, byte_order, FALSE,
495c11401949f29a97414887a01f0d3e6e8fe60ba40Havoc Pennington                                                         total_depth + 1,
496c11401949f29a97414887a01f0d3e6e8fe60ba40Havoc Pennington                                                         p, end, &p);
497e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                        if (validity != DBUS_VALID)
498e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                          return validity;
499e61f13cf328d131ddbd8b49842fcd0f49847dbffJon Gosting                      }
5009c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                  }
5019c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
5029c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                if (p != array_end)
5039c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                  return DBUS_INVALID_ARRAY_LENGTH_INCORRECT;
5049c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington              }
5059c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
5069c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            /* check nul termination */
5079c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            if (current_type != DBUS_TYPE_ARRAY)
5089c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington              {
5099c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                if (p == end)
5109c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                  return DBUS_INVALID_NOT_ENOUGH_DATA;
5119c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
5129c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                if (*p != '\0')
5139c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                  return DBUS_INVALID_STRING_MISSING_NUL;
5149c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                ++p;
5159c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington              }
5169c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          }
5179c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          break;
5189c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
5199c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        case DBUS_TYPE_SIGNATURE:
5209c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          {
5219c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            dbus_uint32_t claimed_len;
5229c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            DBusString str;
5238f04e1e01f51fa9bef564dbaf29be59694407d21Havoc Pennington            DBusValidity validity;
5249c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
5259c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            claimed_len = *p;
5269c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            ++p;
5279c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
5289c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            /* 1 is for nul termination */
5299c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            if (claimed_len + 1 > (unsigned long) (end - p))
5309c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington              return DBUS_INVALID_SIGNATURE_LENGTH_OUT_OF_BOUNDS;
5319c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
5329c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            _dbus_string_init_const_len (&str, p, claimed_len);
5338f04e1e01f51fa9bef564dbaf29be59694407d21Havoc Pennington            validity =
5348f04e1e01f51fa9bef564dbaf29be59694407d21Havoc Pennington              _dbus_validate_signature_with_reason (&str, 0,
5358f04e1e01f51fa9bef564dbaf29be59694407d21Havoc Pennington                                                    _dbus_string_get_length (&str));
5368f04e1e01f51fa9bef564dbaf29be59694407d21Havoc Pennington
5378f04e1e01f51fa9bef564dbaf29be59694407d21Havoc Pennington            if (validity != DBUS_VALID)
5388f04e1e01f51fa9bef564dbaf29be59694407d21Havoc Pennington              return validity;
5399c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
5409c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            p += claimed_len;
5419c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
5429c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            _dbus_assert (p < end);
5439c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            if (*p != DBUS_TYPE_INVALID)
5449c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington              return DBUS_INVALID_SIGNATURE_MISSING_NUL;
5459c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
5469c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            ++p;
5479c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
5489c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            _dbus_verbose ("p = %p end = %p claimed_len %u\n", p, end, claimed_len);
5499c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          }
5509c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          break;
5519c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
5529c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        case DBUS_TYPE_VARIANT:
5539c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          {
554ad937e16957c76f21b0df79d742cb4c401d2abb9Havoc Pennington            /* 1 byte sig len, sig typecodes, align to
555ad937e16957c76f21b0df79d742cb4c401d2abb9Havoc Pennington             * contained-type-boundary, values.
556ad937e16957c76f21b0df79d742cb4c401d2abb9Havoc Pennington             */
557ad937e16957c76f21b0df79d742cb4c401d2abb9Havoc Pennington
5589c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            /* In addition to normal signature validation, we need to be sure
5599c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington             * the signature contains only a single (possibly container) type.
5609c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington             */
5619c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            dbus_uint32_t claimed_len;
5629c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            DBusString sig;
5639c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            DBusTypeReader sub;
5649c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            DBusValidity validity;
565ad937e16957c76f21b0df79d742cb4c401d2abb9Havoc Pennington            int contained_alignment;
5660e53d4eed36f378e99802e516fbb0d1355641902Havoc Pennington            int contained_type;
5675e389fdf499c39926c61b47fcafb5e71291ce1a2John (J            DBusValidity reason;
5689c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
5699c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            claimed_len = *p;
5709c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            ++p;
5719c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
5729c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            /* + 1 for nul */
5739c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            if (claimed_len + 1 > (unsigned long) (end - p))
5749c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington              return DBUS_INVALID_VARIANT_SIGNATURE_LENGTH_OUT_OF_BOUNDS;
5759c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
5769c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            _dbus_string_init_const_len (&sig, p, claimed_len);
5775e389fdf499c39926c61b47fcafb5e71291ce1a2John (J            reason = _dbus_validate_signature_with_reason (&sig, 0,
5785e389fdf499c39926c61b47fcafb5e71291ce1a2John (J                                           _dbus_string_get_length (&sig));
5795e389fdf499c39926c61b47fcafb5e71291ce1a2John (J            if (!(reason == DBUS_VALID))
5805e389fdf499c39926c61b47fcafb5e71291ce1a2John (J              {
5815e389fdf499c39926c61b47fcafb5e71291ce1a2John (J                if (reason == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
5825e389fdf499c39926c61b47fcafb5e71291ce1a2John (J                  return reason;
5835e389fdf499c39926c61b47fcafb5e71291ce1a2John (J                else
5845e389fdf499c39926c61b47fcafb5e71291ce1a2John (J                  return DBUS_INVALID_VARIANT_SIGNATURE_BAD;
5855e389fdf499c39926c61b47fcafb5e71291ce1a2John (J              }
5869c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
5879c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            p += claimed_len;
5888f04e1e01f51fa9bef564dbaf29be59694407d21Havoc Pennington
5899c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            if (*p != DBUS_TYPE_INVALID)
5909c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington              return DBUS_INVALID_VARIANT_SIGNATURE_MISSING_NUL;
5919c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            ++p;
5929c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
5930e53d4eed36f378e99802e516fbb0d1355641902Havoc Pennington            contained_type = _dbus_first_type_in_signature (&sig, 0);
5940e53d4eed36f378e99802e516fbb0d1355641902Havoc Pennington            if (contained_type == DBUS_TYPE_INVALID)
5950e53d4eed36f378e99802e516fbb0d1355641902Havoc Pennington              return DBUS_INVALID_VARIANT_SIGNATURE_EMPTY;
5960e53d4eed36f378e99802e516fbb0d1355641902Havoc Pennington
5970e53d4eed36f378e99802e516fbb0d1355641902Havoc Pennington            contained_alignment = _dbus_type_get_alignment (contained_type);
598ad937e16957c76f21b0df79d742cb4c401d2abb9Havoc Pennington
599ad937e16957c76f21b0df79d742cb4c401d2abb9Havoc Pennington            a = _DBUS_ALIGN_ADDRESS (p, contained_alignment);
6009c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            if (a > end)
6019c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington              return DBUS_INVALID_NOT_ENOUGH_DATA;
6029c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            while (p != a)
6039c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington              {
6049c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                if (*p != '\0')
6059c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                  return DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
6069c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                ++p;
6079c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington              }
6089c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
6099c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            _dbus_type_reader_init_types_only (&sub, &sig, 0);
6109c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
6110e53d4eed36f378e99802e516fbb0d1355641902Havoc Pennington            _dbus_assert (_dbus_type_reader_get_current_type (&sub) != DBUS_TYPE_INVALID);
6129c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
613c11401949f29a97414887a01f0d3e6e8fe60ba40Havoc Pennington            validity = validate_body_helper (&sub, byte_order, FALSE,
614c11401949f29a97414887a01f0d3e6e8fe60ba40Havoc Pennington                                             total_depth + 1,
615c11401949f29a97414887a01f0d3e6e8fe60ba40Havoc Pennington                                             p, end, &p);
6169c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            if (validity != DBUS_VALID)
6179c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington              return validity;
6189c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
6199c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            if (_dbus_type_reader_next (&sub))
6209c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington              return DBUS_INVALID_VARIANT_SIGNATURE_SPECIFIES_MULTIPLE_VALUES;
6219c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
6229c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_INVALID);
6239c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          }
6249c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          break;
6259c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
626c7816d45e82ba8dd7e1e969c2cb6c3a27577cf68Havoc Pennington        case DBUS_TYPE_DICT_ENTRY:
6279c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        case DBUS_TYPE_STRUCT:
6289c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          {
6299c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            DBusTypeReader sub;
6309c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            DBusValidity validity;
6319c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
6329c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            a = _DBUS_ALIGN_ADDRESS (p, 8);
6339c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            if (a > end)
6349c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington              return DBUS_INVALID_NOT_ENOUGH_DATA;
6359c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            while (p != a)
6369c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington              {
6379c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                if (*p != '\0')
6389c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                  return DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
6399c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                ++p;
6409c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington              }
6419c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
6429c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            _dbus_type_reader_recurse (reader, &sub);
6439c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
644c11401949f29a97414887a01f0d3e6e8fe60ba40Havoc Pennington            validity = validate_body_helper (&sub, byte_order, TRUE,
645c11401949f29a97414887a01f0d3e6e8fe60ba40Havoc Pennington                                             total_depth + 1,
646c11401949f29a97414887a01f0d3e6e8fe60ba40Havoc Pennington                                             p, end, &p);
6479c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            if (validity != DBUS_VALID)
6489c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington              return validity;
6499c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          }
6509c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          break;
6519c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
6529c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        default:
6539c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          _dbus_assert_not_reached ("invalid typecode in supposedly-validated signature");
6549c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          break;
6559c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        }
6569c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
65798ad8a8ec6626f7f5c78915b6bdf2be688b4839fHavoc Pennington#if 0
6589c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington      _dbus_verbose ("   validated value of type %s type reader %p type_pos %d p %p end %p %d remain\n",
6599c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                     _dbus_type_to_string (current_type), reader, reader->type_pos, p, end,
6609c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                     (int) (end - p));
66198ad8a8ec6626f7f5c78915b6bdf2be688b4839fHavoc Pennington#endif
6629c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
6639c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington      if (p > end)
6649c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        {
6659c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          _dbus_verbose ("not enough data!!! p = %p end = %p end-p = %d\n",
6669c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                         p, end, (int) (end - p));
6679c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          return DBUS_INVALID_NOT_ENOUGH_DATA;
6689c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        }
6699c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
6709c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington      if (walk_reader_to_end)
6719c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        _dbus_type_reader_next (reader);
6729c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington      else
6739c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        break;
6749c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington    }
6759c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
6769c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  if (new_p)
6779c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington    *new_p = p;
6789c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
6799c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  return DBUS_VALID;
6809c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington}
6819c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
6829c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington/**
6839c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * Verifies that the range of value_str from value_pos to value_end is
6849c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * a legitimate value of type expected_signature.  If this function
6859c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * returns #TRUE, it will be safe to iterate over the values with
6869c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * #DBusTypeReader. The signature is assumed to be already valid.
6879c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington *
6889c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * If bytes_remaining is not #NULL, then leftover bytes will be stored
6899c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * there and #DBUS_VALID returned. If it is #NULL, then
6909c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * #DBUS_INVALID_TOO_MUCH_DATA will be returned if bytes are left
6919c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * over.
6929c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington *
6939c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * @param expected_signature the expected types in the value_str
6949c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * @param expected_signature_start where in expected_signature is the signature
6959c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * @param byte_order the byte order
6969c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * @param bytes_remaining place to store leftover bytes
69731988af4089f3793940417535f8eabaae1ac26c8Havoc Pennington * @param value_str the string containing the body
6989c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * @param value_pos where the values start
6999c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * @param len length of values after value_pos
7009c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * @returns #DBUS_VALID if valid, reason why invalid otherwise
7019c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington */
7029c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc PenningtonDBusValidity
7039c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington_dbus_validate_body_with_reason (const DBusString *expected_signature,
7049c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                                 int               expected_signature_start,
7059c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                                 int               byte_order,
7069c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                                 int              *bytes_remaining,
7079c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                                 const DBusString *value_str,
7089c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                                 int               value_pos,
7099c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                                 int               len)
7109c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington{
7119c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  DBusTypeReader reader;
7129c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  const unsigned char *p;
7139c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  const unsigned char *end;
7149c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  DBusValidity validity;
7159c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
7169c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  _dbus_assert (len >= 0);
7179c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  _dbus_assert (value_pos >= 0);
7189c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  _dbus_assert (value_pos <= _dbus_string_get_length (value_str) - len);
7199c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
7209c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  _dbus_verbose ("validating body from pos %d len %d sig '%s'\n",
7219c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                 value_pos, len, _dbus_string_get_const_data_len (expected_signature,
7229c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                                                                  expected_signature_start,
7239c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                                                                  0));
7249c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
7259c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  _dbus_type_reader_init_types_only (&reader,
7269c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                                     expected_signature, expected_signature_start);
7279c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
7289c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  p = _dbus_string_get_const_data_len (value_str, value_pos, len);
7299c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  end = p + len;
7309c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
731c11401949f29a97414887a01f0d3e6e8fe60ba40Havoc Pennington  validity = validate_body_helper (&reader, byte_order, TRUE, 0, p, end, &p);
7329c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  if (validity != DBUS_VALID)
7339c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington    return validity;
734ad937e16957c76f21b0df79d742cb4c401d2abb9Havoc Pennington
735ad937e16957c76f21b0df79d742cb4c401d2abb9Havoc Pennington  if (bytes_remaining)
7369c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington    {
737ad937e16957c76f21b0df79d742cb4c401d2abb9Havoc Pennington      *bytes_remaining = end - p;
738ad937e16957c76f21b0df79d742cb4c401d2abb9Havoc Pennington      return DBUS_VALID;
739ad937e16957c76f21b0df79d742cb4c401d2abb9Havoc Pennington    }
740ad937e16957c76f21b0df79d742cb4c401d2abb9Havoc Pennington  else if (p < end)
741ad937e16957c76f21b0df79d742cb4c401d2abb9Havoc Pennington    return DBUS_INVALID_TOO_MUCH_DATA;
742ad937e16957c76f21b0df79d742cb4c401d2abb9Havoc Pennington  else
743ad937e16957c76f21b0df79d742cb4c401d2abb9Havoc Pennington    {
744ad937e16957c76f21b0df79d742cb4c401d2abb9Havoc Pennington      _dbus_assert (p == end);
745ad937e16957c76f21b0df79d742cb4c401d2abb9Havoc Pennington      return DBUS_VALID;
7469c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington    }
7479c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington}
7489c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
7499c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington/**
7508b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian * Determine wether the given character is valid as the first character
7514fce285052c143296cd9e08a48de0175b5207853Havoc Pennington * in a name.
7524fce285052c143296cd9e08a48de0175b5207853Havoc Pennington */
7534fce285052c143296cd9e08a48de0175b5207853Havoc Pennington#define VALID_INITIAL_NAME_CHARACTER(c)         \
7544fce285052c143296cd9e08a48de0175b5207853Havoc Pennington  ( ((c) >= 'A' && (c) <= 'Z') ||               \
7554fce285052c143296cd9e08a48de0175b5207853Havoc Pennington    ((c) >= 'a' && (c) <= 'z') ||               \
7564fce285052c143296cd9e08a48de0175b5207853Havoc Pennington    ((c) == '_') )
7574fce285052c143296cd9e08a48de0175b5207853Havoc Pennington
7584fce285052c143296cd9e08a48de0175b5207853Havoc Pennington/**
7598b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian * Determine wether the given character is valid as a second or later
7604fce285052c143296cd9e08a48de0175b5207853Havoc Pennington * character in a name
7614fce285052c143296cd9e08a48de0175b5207853Havoc Pennington */
7624fce285052c143296cd9e08a48de0175b5207853Havoc Pennington#define VALID_NAME_CHARACTER(c)                 \
7634fce285052c143296cd9e08a48de0175b5207853Havoc Pennington  ( ((c) >= '0' && (c) <= '9') ||               \
7644fce285052c143296cd9e08a48de0175b5207853Havoc Pennington    ((c) >= 'A' && (c) <= 'Z') ||               \
7654fce285052c143296cd9e08a48de0175b5207853Havoc Pennington    ((c) >= 'a' && (c) <= 'z') ||               \
7664fce285052c143296cd9e08a48de0175b5207853Havoc Pennington    ((c) == '_') )
7674fce285052c143296cd9e08a48de0175b5207853Havoc Pennington
7684fce285052c143296cd9e08a48de0175b5207853Havoc Pennington/**
7699c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * Checks that the given range of the string is a valid object path
7707652304bff969afb3969603149bb385efe861fe8John (J * name in the D-Bus protocol. Part of the validation ensures that
7719c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * the object path contains only ASCII.
7729c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington *
7739c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * @todo this is inconsistent with most of DBusString in that
7749c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * it allows a start,len range that extends past the string end.
7759c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington *
7769c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * @todo change spec to disallow more things, such as spaces in the
7779c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * path name
7789c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington *
7799c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * @param str the string
7809c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * @param start first byte index to check
7819c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * @param len number of bytes to check
7829c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * @returns #TRUE if the byte range exists and is a valid name
7839c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington */
7849c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Penningtondbus_bool_t
7859c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington_dbus_validate_path (const DBusString  *str,
7869c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                     int                start,
7879c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                     int                len)
7889c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington{
7899c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  const unsigned char *s;
7909c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  const unsigned char *end;
7919c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  const unsigned char *last_slash;
7929c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
7939c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  _dbus_assert (start >= 0);
7949c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  _dbus_assert (len >= 0);
7959c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  _dbus_assert (start <= _dbus_string_get_length (str));
79641f52c96d651003b3d0a266a582d401228a8368eHavoc Pennington
7979c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  if (len > _dbus_string_get_length (str) - start)
7989c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington    return FALSE;
7999c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
8009c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  if (len == 0)
8019c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington    return FALSE;
8029c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
8039c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  s = _dbus_string_get_const_data (str) + start;
8049c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  end = s + len;
8059c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
8069c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  if (*s != '/')
8079c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington    return FALSE;
8089c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  last_slash = s;
8099c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  ++s;
8109c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
8119c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  while (s != end)
8129c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington    {
8139c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington      if (*s == '/')
8149c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        {
8159c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          if ((s - last_slash) < 2)
8169c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            return FALSE; /* no empty path components allowed */
8179c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
8189c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          last_slash = s;
8199c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        }
8209c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington      else
8219c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        {
8224fce285052c143296cd9e08a48de0175b5207853Havoc Pennington          if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*s)))
8239c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            return FALSE;
8249c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        }
8259c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
8269c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington      ++s;
8279c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington    }
8289c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
8299c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  if ((end - last_slash) < 2 &&
8309c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington      len > 1)
8319c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington    return FALSE; /* trailing slash not allowed unless the string is "/" */
8329c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
8339c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  return TRUE;
8349c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington}
8359c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
836099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quinteroconst char *
837099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero_dbus_validity_to_error_message (DBusValidity validity)
838099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero{
839099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero  switch (validity)
840099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    {
841099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_VALIDITY_UNKNOWN_OOM_ERROR:                          return "Out of memory";
842099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_FOR_UNKNOWN_REASON:                          return "Unknown reason";
843099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_VALID_BUT_INCOMPLETE:                                return "Valid but incomplete";
844099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_VALIDITY_UNKNOWN:                                    return "Validity unknown";
845099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_VALID:                                               return "Valid";
846099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_UNKNOWN_TYPECODE:                            return "Unknown typecode";
847099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE:                  return "Missing array element type";
848099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_SIGNATURE_TOO_LONG:                          return "Signature is too long";
849099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_EXCEEDED_MAXIMUM_ARRAY_RECURSION:            return "Exceeded maximum array recursion";
850099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_EXCEEDED_MAXIMUM_STRUCT_RECURSION:           return "Exceeded maximum struct recursion";
851099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_STRUCT_ENDED_BUT_NOT_STARTED:                return "Struct ended but not started";
852099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_STRUCT_STARTED_BUT_NOT_ENDED:                return "Struct started but not ended";
853099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_STRUCT_HAS_NO_FIELDS:                        return "Struct has no fields";
854099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL:                   return "Alignment padding not null";
855099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_BOOLEAN_NOT_ZERO_OR_ONE:                     return "Boolean is not zero or one";
856099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_NOT_ENOUGH_DATA:                             return "Not enough data";
857099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_TOO_MUCH_DATA:                               return "Too much data";
858099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_BAD_BYTE_ORDER:                              return "Bad byte order";
859099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_BAD_PROTOCOL_VERSION:                        return "Bad protocol version";
860099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_BAD_MESSAGE_TYPE:                            return "Bad message type";
861099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_BAD_SERIAL:                                  return "Bad serial";
862099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_INSANE_FIELDS_ARRAY_LENGTH:                  return "Insane fields array length";
863099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_INSANE_BODY_LENGTH:                          return "Insane body length";
864099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_MESSAGE_TOO_LONG:                            return "Message too long";
865099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_HEADER_FIELD_CODE:                           return "Header field code";
866099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_HEADER_FIELD_HAS_WRONG_TYPE:                 return "Header field has wrong type";
867099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_USES_LOCAL_INTERFACE:                        return "Uses local interface";
868099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_USES_LOCAL_PATH:                             return "Uses local path";
869099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_HEADER_FIELD_APPEARS_TWICE:                  return "Header field appears twice";
870099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_BAD_DESTINATION:                             return "Bad destination";
871099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_BAD_INTERFACE:                               return "Bad interface";
872099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_BAD_MEMBER:                                  return "Bad member";
873099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_BAD_ERROR_NAME:                              return "Bad error name";
874099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_BAD_SENDER:                                  return "Bad sender";
875099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_MISSING_PATH:                                return "Missing path";
876099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_MISSING_INTERFACE:                           return "Missing interface";
877099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_MISSING_MEMBER:                              return "Missing member";
878099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_MISSING_ERROR_NAME:                          return "Missing error name";
879099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_MISSING_REPLY_SERIAL:                        return "Missing reply serial";
880099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_LENGTH_OUT_OF_BOUNDS:                        return "Length out of bounds";
881099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_ARRAY_LENGTH_EXCEEDS_MAXIMUM:                return "Array length exceeds maximum";
882099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_BAD_PATH:                                    return "Bad path";
883099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_SIGNATURE_LENGTH_OUT_OF_BOUNDS:              return "Signature length out of bounds";
884099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_BAD_UTF8_IN_STRING:                          return "Bad utf8 in string";
885099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_ARRAY_LENGTH_INCORRECT:                      return "Array length incorrect";
886099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_VARIANT_SIGNATURE_LENGTH_OUT_OF_BOUNDS:      return "Variant signature length out of bounds";
887099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_VARIANT_SIGNATURE_BAD:                       return "Variant signature bad";
888099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_VARIANT_SIGNATURE_EMPTY:                     return "Variant signature empty";
889099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_VARIANT_SIGNATURE_SPECIFIES_MULTIPLE_VALUES: return "Variant signature specifies multiple values";
890099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_VARIANT_SIGNATURE_MISSING_NUL:               return "Variant signature missing nul";
891099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_STRING_MISSING_NUL:                          return "String missing nul";
892099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_SIGNATURE_MISSING_NUL:                       return "Signature missing nul";
893099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_EXCEEDED_MAXIMUM_DICT_ENTRY_RECURSION:       return "Exceeded maximum dict entry recursion";
894099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_DICT_ENTRY_ENDED_BUT_NOT_STARTED:            return "Dict entry ended but not started";
895099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_DICT_ENTRY_STARTED_BUT_NOT_ENDED:            return "Dict entry started but not ended";
896099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_DICT_ENTRY_HAS_NO_FIELDS:                    return "Dict entry has no fields";
897099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_DICT_ENTRY_HAS_ONLY_ONE_FIELD:               return "Dict entry has only one field";
898099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_DICT_ENTRY_HAS_TOO_MANY_FIELDS:              return "Dict entry has too many fields";
899099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_DICT_ENTRY_NOT_INSIDE_ARRAY:                 return "Dict entry not inside array";
900099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    case DBUS_INVALID_DICT_KEY_MUST_BE_BASIC_TYPE:                 return "Dict key must be basic type";
901c11401949f29a97414887a01f0d3e6e8fe60ba40Havoc Pennington    case DBUS_INVALID_NESTED_TOO_DEEPLY:                           return "Variants cannot be used to create a hugely recursive tree of values";
902099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    default:
903099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero      return "Invalid";
904099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero    }
905099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero}
906099b5e59ea84d72bfe29a17e0934f6b2f492ddf3Federico Mena Quintero
9079c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington/**
9089c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * Checks that the given range of the string is a valid interface name
9097652304bff969afb3969603149bb385efe861fe8John (J * in the D-Bus protocol. This includes a length restriction and an
9109c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * ASCII subset, see the specification.
9119c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington *
9129c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * @todo this is inconsistent with most of DBusString in that
9139c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * it allows a start,len range that extends past the string end.
9149c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington *
9159c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * @param str the string
9169c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * @param start first byte index to check
9179c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * @param len number of bytes to check
9189c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * @returns #TRUE if the byte range exists and is a valid name
9199c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington */
9209c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Penningtondbus_bool_t
9219c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington_dbus_validate_interface (const DBusString  *str,
9229c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                          int                start,
9239c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                          int                len)
9249c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington{
9259c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  const unsigned char *s;
9269c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  const unsigned char *end;
9279c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  const unsigned char *iface;
9289c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  const unsigned char *last_dot;
9299c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
9309c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  _dbus_assert (start >= 0);
9319c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  _dbus_assert (len >= 0);
9329c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  _dbus_assert (start <= _dbus_string_get_length (str));
9339c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
9349c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  if (len > _dbus_string_get_length (str) - start)
9359c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington    return FALSE;
9369c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
9379c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  if (len > DBUS_MAXIMUM_NAME_LENGTH)
9389c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington    return FALSE;
9399c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
9409c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  if (len == 0)
9419c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington    return FALSE;
9429c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
9439c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  last_dot = NULL;
9449c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  iface = _dbus_string_get_const_data (str) + start;
9459c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  end = iface + len;
9469c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  s = iface;
9479c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
9489c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  /* check special cases of first char so it doesn't have to be done
9499c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington   * in the loop. Note we know len > 0
9509c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington   */
9519c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  if (_DBUS_UNLIKELY (*s == '.')) /* disallow starting with a . */
9529c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington    return FALSE;
9539c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  else if (_DBUS_UNLIKELY (!VALID_INITIAL_NAME_CHARACTER (*s)))
9549c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington    return FALSE;
9559c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  else
9569c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington    ++s;
9579c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
9589c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  while (s != end)
9599c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington    {
9609c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington      if (*s == '.')
9619c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        {
9629c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          if (_DBUS_UNLIKELY ((s + 1) == end))
9639c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            return FALSE;
9649c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          else if (_DBUS_UNLIKELY (!VALID_INITIAL_NAME_CHARACTER (*(s + 1))))
9659c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            return FALSE;
9669c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          last_dot = s;
9679c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          ++s; /* we just validated the next char, so skip two */
9689c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        }
9699c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington      else if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*s)))
9709c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        {
9719c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          return FALSE;
9729c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        }
9739c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
9749c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington      ++s;
9759c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington    }
9769c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
9779c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  if (_DBUS_UNLIKELY (last_dot == NULL))
9789c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington    return FALSE;
9799c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
9809c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  return TRUE;
9819c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington}
9829c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
9839c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington/**
9849c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * Checks that the given range of the string is a valid member name
9857652304bff969afb3969603149bb385efe861fe8John (J * in the D-Bus protocol. This includes a length restriction, etc.,
9869c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * see the specification.
9879c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington *
9889c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * @todo this is inconsistent with most of DBusString in that
9899c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * it allows a start,len range that extends past the string end.
9909c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington *
9919c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * @param str the string
9929c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * @param start first byte index to check
9939c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * @param len number of bytes to check
9949c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * @returns #TRUE if the byte range exists and is a valid name
9959c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington */
9969c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Penningtondbus_bool_t
9979c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington_dbus_validate_member (const DBusString  *str,
9989c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                       int                start,
9999c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                       int                len)
10009c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington{
10019c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  const unsigned char *s;
10029c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  const unsigned char *end;
10039c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  const unsigned char *member;
10049c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
10059c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  _dbus_assert (start >= 0);
10069c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  _dbus_assert (len >= 0);
10079c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  _dbus_assert (start <= _dbus_string_get_length (str));
10089c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
10099c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  if (len > _dbus_string_get_length (str) - start)
10109c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington    return FALSE;
10119c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
10129c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  if (len > DBUS_MAXIMUM_NAME_LENGTH)
10139c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington    return FALSE;
10149c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
10159c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  if (len == 0)
10169c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington    return FALSE;
10179c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
10189c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  member = _dbus_string_get_const_data (str) + start;
10199c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  end = member + len;
10209c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  s = member;
10219c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
10229c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  /* check special cases of first char so it doesn't have to be done
10239c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington   * in the loop. Note we know len > 0
10249c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington   */
10259c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
10269c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  if (_DBUS_UNLIKELY (!VALID_INITIAL_NAME_CHARACTER (*s)))
10279c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington    return FALSE;
10289c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  else
10299c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington    ++s;
10309c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
10319c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  while (s != end)
10329c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington    {
10339c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington      if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*s)))
10349c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        {
10359c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          return FALSE;
10369c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        }
10379c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
10389c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington      ++s;
10399c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington    }
10409c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
10419c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  return TRUE;
10429c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington}
10439c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
10449c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington/**
10459c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * Checks that the given range of the string is a valid error name
10467652304bff969afb3969603149bb385efe861fe8John (J * in the D-Bus protocol. This includes a length restriction, etc.,
10479c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * see the specification.
10489c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington *
10499c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * @todo this is inconsistent with most of DBusString in that
10509c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * it allows a start,len range that extends past the string end.
10519c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington *
10529c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * @param str the string
10539c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * @param start first byte index to check
10549c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * @param len number of bytes to check
10559c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * @returns #TRUE if the byte range exists and is a valid name
10569c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington */
10579c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Penningtondbus_bool_t
10589c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington_dbus_validate_error_name (const DBusString  *str,
10599c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                           int                start,
10609c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                           int                len)
10619c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington{
10629c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  /* Same restrictions as interface name at the moment */
10639c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  return _dbus_validate_interface (str, start, len);
10649c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington}
10659c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
10668b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian/**
10678b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian * Determine wether the given character is valid as the first character
10688b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian * in a bus name.
10698b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian */
10708b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian#define VALID_INITIAL_BUS_NAME_CHARACTER(c)         \
10718b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian  ( ((c) >= 'A' && (c) <= 'Z') ||               \
10728b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian    ((c) >= 'a' && (c) <= 'z') ||               \
10738b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian    ((c) == '_') || ((c) == '-'))
10748b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian
10758b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian/**
10768b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian * Determine wether the given character is valid as a second or later
10778b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian * character in a bus name
10788b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian */
10798b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian#define VALID_BUS_NAME_CHARACTER(c)                 \
10808b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian  ( ((c) >= '0' && (c) <= '9') ||               \
10818b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian    ((c) >= 'A' && (c) <= 'Z') ||               \
10828b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian    ((c) >= 'a' && (c) <= 'z') ||               \
10838b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian    ((c) == '_') || ((c) == '-'))
10848b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian
10858b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian/**
10868b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian * Checks that the given range of the string is a valid bus name in
10877652304bff969afb3969603149bb385efe861fe8John (J * the D-Bus protocol. This includes a length restriction, etc., see
10888b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian * the specification.
10898b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian *
10908b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian * @todo this is inconsistent with most of DBusString in that
10918b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian * it allows a start,len range that extends past the string end.
10928b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian *
10938b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian * @param str the string
10948b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian * @param start first byte index to check
10958b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian * @param len number of bytes to check
10968b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian * @returns #TRUE if the byte range exists and is a valid name
10978b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian */
10988b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastiandbus_bool_t
10998b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian_dbus_validate_bus_name (const DBusString  *str,
11008b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian                         int                start,
11018b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian                         int                len)
11029c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington{
11039c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  const unsigned char *s;
11049c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  const unsigned char *end;
11058b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian  const unsigned char *iface;
11068b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian  const unsigned char *last_dot;
11079c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
11089c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  _dbus_assert (start >= 0);
11099c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  _dbus_assert (len >= 0);
11109c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  _dbus_assert (start <= _dbus_string_get_length (str));
11119c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
11129c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  if (len > _dbus_string_get_length (str) - start)
11139c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington    return FALSE;
11149c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
11159c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  if (len > DBUS_MAXIMUM_NAME_LENGTH)
11169c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington    return FALSE;
11179c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
11188b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian  if (len == 0)
11198b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian    return FALSE;
11209c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
11218b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian  last_dot = NULL;
11228b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian  iface = _dbus_string_get_const_data (str) + start;
11238b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian  end = iface + len;
11248b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian  s = iface;
11258b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian
11268b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian  /* check special cases of first char so it doesn't have to be done
11278b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian   * in the loop. Note we know len > 0
11288b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian   */
11298b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian  if (*s == ':')
11308b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian  {
11318b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian    /* unique name */
11328b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian    ++s;
11338b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian    while (s != end)
11348b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian      {
11358b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian        if (*s == '.')
11368b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian          {
11378b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian            if (_DBUS_UNLIKELY ((s + 1) == end))
11388b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian              return FALSE;
11398b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian            if (_DBUS_UNLIKELY (!VALID_BUS_NAME_CHARACTER (*(s + 1))))
11408b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian              return FALSE;
11418b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian            ++s; /* we just validated the next char, so skip two */
11428b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian          }
11438b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian        else if (_DBUS_UNLIKELY (!VALID_BUS_NAME_CHARACTER (*s)))
11448b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian          {
11458b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian            return FALSE;
11468b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian          }
11478b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian
11488b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian        ++s;
11498b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian      }
11508b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian
11518b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian    return TRUE;
11528b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian  }
11538b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian  else if (_DBUS_UNLIKELY (*s == '.')) /* disallow starting with a . */
11548b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian    return FALSE;
11558b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian  else if (_DBUS_UNLIKELY (!VALID_INITIAL_BUS_NAME_CHARACTER (*s)))
11568b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian    return FALSE;
11578b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian  else
11588b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian    ++s;
11599c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
11609c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  while (s != end)
11619c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington    {
11629c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington      if (*s == '.')
11639c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        {
11649c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          if (_DBUS_UNLIKELY ((s + 1) == end))
11659c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            return FALSE;
11668b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian          else if (_DBUS_UNLIKELY (!VALID_INITIAL_BUS_NAME_CHARACTER (*(s + 1))))
11679c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington            return FALSE;
11688b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian          last_dot = s;
11699c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          ++s; /* we just validated the next char, so skip two */
11709c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        }
11718b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian      else if (_DBUS_UNLIKELY (!VALID_BUS_NAME_CHARACTER (*s)))
11729c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        {
11739c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington          return FALSE;
11749c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington        }
11759c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
11769c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington      ++s;
11779c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington    }
11789c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
11798b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian  if (_DBUS_UNLIKELY (last_dot == NULL))
11809c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington    return FALSE;
11818b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian
11828b34c2c538f182fe29af58f5153b9dd7cdbaf7faWaldo Bastian  return TRUE;
11839c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington}
11849c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
11859c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington/**
11869c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * Checks that the given range of the string is a valid message type
11877652304bff969afb3969603149bb385efe861fe8John (J * signature in the D-Bus protocol.
11889c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington *
11899c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * @todo this is inconsistent with most of DBusString in that
11909c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * it allows a start,len range that extends past the string end.
11919c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington *
11929c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * @param str the string
11939c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * @param start first byte index to check
11949c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * @param len number of bytes to check
11959c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington * @returns #TRUE if the byte range exists and is a valid signature
11969c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington */
11979c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Penningtondbus_bool_t
11989c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington_dbus_validate_signature (const DBusString  *str,
11999c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                          int                start,
12009c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington                          int                len)
12019c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington{
12029c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  _dbus_assert (start >= 0);
12039c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  _dbus_assert (start <= _dbus_string_get_length (str));
12049c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  _dbus_assert (len >= 0);
12059c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
12069c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  if (len > _dbus_string_get_length (str) - start)
12079c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington    return FALSE;
12089c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
12099c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington  return _dbus_validate_signature_with_reason (str, start, len) == DBUS_VALID;
12109c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington}
12119c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
121231988af4089f3793940417535f8eabaae1ac26c8Havoc Pennington/** define _dbus_check_is_valid_path() */
12132349aa6d711d0abc938edd05e2e483813f6e720eSimon McVittieDEFINE_DBUS_NAME_CHECK(path)
121431988af4089f3793940417535f8eabaae1ac26c8Havoc Pennington/** define _dbus_check_is_valid_interface() */
12152349aa6d711d0abc938edd05e2e483813f6e720eSimon McVittieDEFINE_DBUS_NAME_CHECK(interface)
121631988af4089f3793940417535f8eabaae1ac26c8Havoc Pennington/** define _dbus_check_is_valid_member() */
12172349aa6d711d0abc938edd05e2e483813f6e720eSimon McVittieDEFINE_DBUS_NAME_CHECK(member)
121831988af4089f3793940417535f8eabaae1ac26c8Havoc Pennington/** define _dbus_check_is_valid_error_name() */
12192349aa6d711d0abc938edd05e2e483813f6e720eSimon McVittieDEFINE_DBUS_NAME_CHECK(error_name)
12208873c90f99303f9cc308f15f8d03e637911f5b9eHavoc Pennington/** define _dbus_check_is_valid_bus_name() */
12212349aa6d711d0abc938edd05e2e483813f6e720eSimon McVittieDEFINE_DBUS_NAME_CHECK(bus_name)
122231988af4089f3793940417535f8eabaae1ac26c8Havoc Pennington/** define _dbus_check_is_valid_signature() */
12232349aa6d711d0abc938edd05e2e483813f6e720eSimon McVittieDEFINE_DBUS_NAME_CHECK(signature)
12249c3d566e95c9080f6040c64531b0ccae22bd5d74Havoc Pennington
12255c486a24e50ef731b8f970060ab10e928cd0e7cdHavoc Pennington/** @} */
12265c486a24e50ef731b8f970060ab10e928cd0e7cdHavoc Pennington
1227382d5ad0b4adf0070948fc2da623bc52894a7788Havoc Pennington/* tests in dbus-marshal-validate-util.c */
1228