Update NEWS
[dbus-python-phuang.git] / _dbus_bindings / validation.c
blobab5d8cc9f30224c2a4060bb41245ad8107bd86f6
1 /* Implementation of various validation functions for use in dbus-python.
3 * Copyright (C) 2006 Collabora Ltd. <http://www.collabora.co.uk/>
5 * Licensed under the Academic Free License version 2.1
7 * This library is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published by
9 * the Free Software Foundation; either version 2.1 of the License, or
10 * (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "dbus_bindings-internal.h"
25 dbus_bool_t
26 dbus_py_validate_bus_name(const char *name,
27 dbus_bool_t may_be_unique,
28 dbus_bool_t may_be_not_unique)
30 dbus_bool_t dot = FALSE;
31 dbus_bool_t unique;
32 char last;
33 const char *ptr;
35 if (name[0] == '\0') {
36 PyErr_SetString(PyExc_ValueError, "Invalid bus name: "
37 "may not be empty");
38 return FALSE;
40 unique = (name[0] == ':');
41 if (unique && !may_be_unique) {
42 PyErr_Format(PyExc_ValueError, "Invalid well-known bus name '%s':"
43 "only unique names may start with ':'", name);
44 return FALSE;
46 if (!unique && !may_be_not_unique) {
47 PyErr_Format(PyExc_ValueError, "Invalid unique bus name '%s': "
48 "unique names must start with ':'", name);
49 return FALSE;
51 if (strlen(name) > 255) {
52 PyErr_Format(PyExc_ValueError, "Invalid bus name '%s': "
53 "too long (> 255 characters)", name);
54 return FALSE;
56 last = '\0';
57 for (ptr = name + (unique ? 1 : 0); *ptr; ptr++) {
58 if (*ptr == '.') {
59 dot = TRUE;
60 if (last == '.') {
61 PyErr_Format(PyExc_ValueError, "Invalid bus name '%s': "
62 "contains substring '..'", name);
63 return FALSE;
65 else if (last == '\0') {
66 PyErr_Format(PyExc_ValueError, "Invalid bus name '%s': "
67 "must not start with '.'", name);
68 return FALSE;
71 else if (*ptr >= '0' && *ptr <= '9') {
72 if (!unique) {
73 if (last == '.') {
74 PyErr_Format(PyExc_ValueError, "Invalid bus name '%s': "
75 "a digit may not follow '.' except in a "
76 "unique name starting with ':'", name);
77 return FALSE;
79 else if (last == '\0') {
80 PyErr_Format(PyExc_ValueError, "Invalid bus name '%s': "
81 "must not start with a digit", name);
82 return FALSE;
86 else if ((*ptr < 'a' || *ptr > 'z') &&
87 (*ptr < 'A' || *ptr > 'Z') && *ptr != '_' && *ptr != '-') {
88 PyErr_Format(PyExc_ValueError, "Invalid bus name '%s': "
89 "contains invalid character '%c'", name, *ptr);
90 return FALSE;
92 last = *ptr;
94 if (last == '.') {
95 PyErr_Format(PyExc_ValueError, "Invalid bus name '%s': must "
96 "not end with '.'", name);
97 return FALSE;
99 if (!dot) {
100 PyErr_Format(PyExc_ValueError, "Invalid bus name '%s': must "
101 "contain '.'", name);
102 return FALSE;
104 return TRUE;
107 dbus_bool_t
108 dbus_py_validate_member_name(const char *name)
110 const char *ptr;
112 if (name[0] == '\0') {
113 PyErr_SetString(PyExc_ValueError, "Invalid member name: may not "
114 "be empty");
115 return FALSE;
117 if (strlen(name) > 255) {
118 PyErr_Format(PyExc_ValueError, "Invalid member name '%s': "
119 "too long (> 255 characters)", name);
120 return FALSE;
122 for (ptr = name; *ptr; ptr++) {
123 if (*ptr >= '0' && *ptr <= '9') {
124 if (ptr == name) {
125 PyErr_Format(PyExc_ValueError, "Invalid member name '%s': "
126 "must not start with a digit", name);
127 return FALSE;
130 else if ((*ptr < 'a' || *ptr > 'z') &&
131 (*ptr < 'A' || *ptr > 'Z') && *ptr != '_') {
132 PyErr_Format(PyExc_ValueError, "Invalid member name '%s': "
133 "contains invalid character '%c'", name, *ptr);
134 return FALSE;
137 return TRUE;
140 dbus_bool_t
141 dbus_py_validate_interface_name(const char *name)
143 dbus_bool_t dot = FALSE;
144 char last;
145 const char *ptr;
147 if (name[0] == '\0') {
148 PyErr_SetString(PyExc_ValueError, "Invalid interface or error name: "
149 "may not be empty");
150 return FALSE;
152 if (strlen(name) > 255) {
153 PyErr_Format(PyExc_ValueError, "Invalid interface or error name '%s': "
154 "too long (> 255 characters)", name);
155 return FALSE;
157 last = '\0';
158 for (ptr = name; *ptr; ptr++) {
159 if (*ptr == '.') {
160 dot = TRUE;
161 if (last == '.') {
162 PyErr_Format(PyExc_ValueError, "Invalid interface or "
163 "error name '%s': contains substring '..'", name);
164 return FALSE;
166 else if (last == '\0') {
167 PyErr_Format(PyExc_ValueError, "Invalid interface or error "
168 "name '%s': must not start with '.'", name);
169 return FALSE;
172 else if (*ptr >= '0' && *ptr <= '9') {
173 if (last == '.') {
174 PyErr_Format(PyExc_ValueError, "Invalid interface or error "
175 "name '%s': a digit may not follow '.'", name);
176 return FALSE;
178 else if (last == '\0') {
179 PyErr_Format(PyExc_ValueError, "Invalid interface or error "
180 "name '%s': must not start with a digit", name);
181 return FALSE;
184 else if ((*ptr < 'a' || *ptr > 'z') &&
185 (*ptr < 'A' || *ptr > 'Z') && *ptr != '_') {
186 PyErr_Format(PyExc_ValueError, "Invalid interface or error "
187 "name '%s': contains invalid character '%c'",
188 name, *ptr);
189 return FALSE;
191 last = *ptr;
193 if (last == '.') {
194 PyErr_Format(PyExc_ValueError, "Invalid interface or error name "
195 "'%s': must not end with '.'", name);
196 return FALSE;
198 if (!dot) {
199 PyErr_Format(PyExc_ValueError, "Invalid interface or error name "
200 "'%s': must contain '.'", name);
201 return FALSE;
203 return TRUE;
207 dbus_bool_t
208 dbus_py_validate_object_path(const char *path)
210 const char *ptr;
212 if (path[0] != '/') {
213 PyErr_Format(PyExc_ValueError, "Invalid object path '%s': does not "
214 "start with '/'", path);
215 return FALSE;
217 if (path[1] == '\0') return TRUE;
218 for (ptr = path + 1; *ptr; ptr++) {
219 if (*ptr == '/') {
220 if (ptr[-1] == '/') {
221 PyErr_Format(PyExc_ValueError, "Invalid object path '%s': "
222 "contains substring '//'", path);
223 return FALSE;
226 else if ((*ptr < 'a' || *ptr > 'z') &&
227 (*ptr < 'A' || *ptr > 'Z') &&
228 (*ptr < '0' || *ptr > '9') && *ptr != '_') {
229 PyErr_Format(PyExc_ValueError, "Invalid object path '%s': "
230 "contains invalid character '%c'", path, *ptr);
231 return FALSE;
234 if (ptr[-1] == '/') {
235 PyErr_Format(PyExc_ValueError, "Invalid object path '%s': ends "
236 "with '/' and is not just '/'", path);
237 return FALSE;
239 return TRUE;
242 /* vim:set ft=c cino< sw=4 sts=4 et: */