1/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2/* dbus-syntax.c - utility functions for strings with special syntax
3 *
4 * Author: Simon McVittie <simon.mcvittie@collabora.co.uk>
5 * Copyright �� 2011 Nokia Corporation
6 *
7 * Licensed under the Academic Free License version 2.1
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22 *
23 */
24
25#include <config.h>
26#include "dbus-syntax.h"
27
28#include "dbus-internals.h"
29#include "dbus-marshal-validate.h"
30#include "dbus-shared.h"
31
32/**
33 * @defgroup DBusSyntax Utility functions for strings with special syntax
34 * @ingroup  DBus
35 * @brief Parsing D-Bus type signatures
36 * @{
37 */
38
39/**
40 * Check an object path for validity. Remember that #NULL can always
41 * be passed instead of a DBusError *, if you don't care about having
42 * an error name and message.
43 *
44 * This function is suitable for validating C strings, but is not suitable
45 * for validating untrusted data from a network unless the string's length
46 * is also checked, since it assumes that the string ends at the first zero
47 * byte according to normal C conventions.
48 *
49 * @param path a potentially invalid object path, which must not be #NULL
50 * @param error error return
51 * @returns #TRUE if path is valid
52 */
53dbus_bool_t
54dbus_validate_path (const char       *path,
55                    DBusError        *error)
56{
57  DBusString str;
58  int len;
59
60  _dbus_return_val_if_fail (path != NULL, FALSE);
61
62  _dbus_string_init_const (&str, path);
63  len = _dbus_string_get_length (&str);
64
65  /* In general, it ought to be valid... */
66  if (_DBUS_LIKELY (_dbus_validate_path (&str, 0, len)))
67    return TRUE;
68
69  /* slow path: string is invalid, find out why */
70
71  if (!_dbus_string_validate_utf8 (&str, 0, len))
72    {
73      /* don't quote the actual string here, since a DBusError also needs to
74       * be valid UTF-8 */
75      dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
76                      "Object path was not valid UTF-8");
77      return FALSE;
78    }
79
80  /* FIXME: later, diagnose exactly how it was invalid */
81  dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
82                  "Object path was not valid: '%s'", path);
83  return FALSE;
84}
85
86/**
87 * Check an interface name for validity. Remember that #NULL can always
88 * be passed instead of a DBusError *, if you don't care about having
89 * an error name and message.
90 *
91 * This function is suitable for validating C strings, but is not suitable
92 * for validating untrusted data from a network unless the string's length
93 * is also checked, since it assumes that the string ends at the first zero
94 * byte according to normal C conventions.
95 *
96 * @param path a potentially invalid interface name, which must not be #NULL
97 * @param error error return
98 * @returns #TRUE if name is valid
99 */
100dbus_bool_t
101dbus_validate_interface (const char       *name,
102                         DBusError        *error)
103{
104  DBusString str;
105  int len;
106
107  _dbus_return_val_if_fail (name != NULL, FALSE);
108
109  _dbus_string_init_const (&str, name);
110  len = _dbus_string_get_length (&str);
111
112  /* In general, it ought to be valid... */
113  if (_DBUS_LIKELY (_dbus_validate_interface (&str, 0, len)))
114    return TRUE;
115
116  /* slow path: string is invalid, find out why */
117
118  if (!_dbus_string_validate_utf8 (&str, 0, len))
119    {
120      /* don't quote the actual string here, since a DBusError also needs to
121       * be valid UTF-8 */
122      dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
123                      "Interface name was not valid UTF-8");
124      return FALSE;
125    }
126
127  /* FIXME: later, diagnose exactly how it was invalid */
128  dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
129                  "Interface name was not valid: '%s'", name);
130  return FALSE;
131}
132
133/**
134 * Check a member (method/signal) name for validity. Remember that #NULL
135 * can always be passed instead of a DBusError *, if you don't care about
136 * having an error name and message.
137 *
138 * This function is suitable for validating C strings, but is not suitable
139 * for validating untrusted data from a network unless the string's length
140 * is also checked, since it assumes that the string ends at the first zero
141 * byte according to normal C conventions.
142 *
143 * @param path a potentially invalid member name, which must not be #NULL
144 * @param error error return
145 * @returns #TRUE if name is valid
146 */
147dbus_bool_t
148dbus_validate_member (const char       *name,
149                      DBusError        *error)
150{
151  DBusString str;
152  int len;
153
154  _dbus_return_val_if_fail (name != NULL, FALSE);
155
156  _dbus_string_init_const (&str, name);
157  len = _dbus_string_get_length (&str);
158
159  /* In general, it ought to be valid... */
160  if (_DBUS_LIKELY (_dbus_validate_member (&str, 0, len)))
161    return TRUE;
162
163  /* slow path: string is invalid, find out why */
164
165  if (!_dbus_string_validate_utf8 (&str, 0, len))
166    {
167      /* don't quote the actual string here, since a DBusError also needs to
168       * be valid UTF-8 */
169      dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
170                      "Member name was not valid UTF-8");
171      return FALSE;
172    }
173
174  /* FIXME: later, diagnose exactly how it was invalid */
175  dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
176                  "Member name was not valid: '%s'", name);
177  return FALSE;
178}
179
180/**
181 * Check an error name for validity. Remember that #NULL
182 * can always be passed instead of a DBusError *, if you don't care about
183 * having an error name and message.
184 *
185 * This function is suitable for validating C strings, but is not suitable
186 * for validating untrusted data from a network unless the string's length
187 * is also checked, since it assumes that the string ends at the first zero
188 * byte according to normal C conventions.
189 *
190 * @param path a potentially invalid error name, which must not be #NULL
191 * @param error error return
192 * @returns #TRUE if name is valid
193 */
194dbus_bool_t
195dbus_validate_error_name (const char       *name,
196                          DBusError        *error)
197{
198  DBusString str;
199  int len;
200
201  _dbus_return_val_if_fail (name != NULL, FALSE);
202
203  _dbus_string_init_const (&str, name);
204  len = _dbus_string_get_length (&str);
205
206  /* In general, it ought to be valid... */
207  if (_DBUS_LIKELY (_dbus_validate_error_name (&str, 0, len)))
208    return TRUE;
209
210  /* slow path: string is invalid, find out why */
211
212  if (!_dbus_string_validate_utf8 (&str, 0, len))
213    {
214      /* don't quote the actual string here, since a DBusError also needs to
215       * be valid UTF-8 */
216      dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
217                      "Error name was not valid UTF-8");
218      return FALSE;
219    }
220
221  /* FIXME: later, diagnose exactly how it was invalid */
222  dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
223                  "Error name was not valid: '%s'", name);
224  return FALSE;
225}
226
227/**
228 * Check a bus name for validity. Remember that #NULL
229 * can always be passed instead of a DBusError *, if you don't care about
230 * having an error name and message.
231 *
232 * This function is suitable for validating C strings, but is not suitable
233 * for validating untrusted data from a network unless the string's length
234 * is also checked, since it assumes that the string ends at the first zero
235 * byte according to normal C conventions.
236 *
237 * @param path a potentially invalid bus name, which must not be #NULL
238 * @param error error return
239 * @returns #TRUE if name is valid
240 */
241dbus_bool_t
242dbus_validate_bus_name (const char       *name,
243                        DBusError        *error)
244{
245  DBusString str;
246  int len;
247
248  _dbus_return_val_if_fail (name != NULL, FALSE);
249
250  _dbus_string_init_const (&str, name);
251  len = _dbus_string_get_length (&str);
252
253  /* In general, it ought to be valid... */
254  if (_DBUS_LIKELY (_dbus_validate_bus_name (&str, 0, len)))
255    return TRUE;
256
257  /* slow path: string is invalid, find out why */
258
259  if (!_dbus_string_validate_utf8 (&str, 0, len))
260    {
261      /* don't quote the actual string here, since a DBusError also needs to
262       * be valid UTF-8 */
263      dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
264                      "Bus name was not valid UTF-8");
265      return FALSE;
266    }
267
268  /* FIXME: later, diagnose exactly how it was invalid */
269  dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
270                  "Bus name was not valid: '%s'", name);
271  return FALSE;
272}
273
274/**
275 * Check a string for validity. Strings on D-Bus must be valid UTF-8.
276 * Remember that #NULL can always be passed instead of a DBusError *,
277 * if you don't care about having an error name and message.
278 *
279 * This function is suitable for validating C strings, but is not suitable
280 * for validating untrusted data from a network unless the string's length
281 * is also checked, since it assumes that the string ends at the first zero
282 * byte according to normal C conventions.
283 *
284 * @param alleged_utf8 a string to be checked, which must not be #NULL
285 * @param error error return
286 * @returns #TRUE if alleged_utf8 is valid UTF-8
287 */
288dbus_bool_t
289dbus_validate_utf8 (const char       *alleged_utf8,
290                    DBusError        *error)
291{
292  DBusString str;
293
294  _dbus_return_val_if_fail (alleged_utf8 != NULL, FALSE);
295
296  _dbus_string_init_const (&str, alleged_utf8);
297
298  if (_DBUS_LIKELY (_dbus_string_validate_utf8 (&str, 0,
299                                                _dbus_string_get_length (&str))))
300    return TRUE;
301
302  /* don't quote the actual string here, since a DBusError also needs to
303   * be valid UTF-8 */
304  dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
305                  "String was not valid UTF-8");
306  return FALSE;
307}
308
309/** @} */ /* end of group */
310