|
Packit |
130fc8 |
/* Implementation of various validation functions for use in dbus-python.
|
|
Packit |
130fc8 |
*
|
|
Packit |
130fc8 |
* Copyright (C) 2006 Collabora Ltd. <http://www.collabora.co.uk/>
|
|
Packit |
130fc8 |
*
|
|
Packit |
130fc8 |
* Permission is hereby granted, free of charge, to any person
|
|
Packit |
130fc8 |
* obtaining a copy of this software and associated documentation
|
|
Packit |
130fc8 |
* files (the "Software"), to deal in the Software without
|
|
Packit |
130fc8 |
* restriction, including without limitation the rights to use, copy,
|
|
Packit |
130fc8 |
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
Packit |
130fc8 |
* of the Software, and to permit persons to whom the Software is
|
|
Packit |
130fc8 |
* furnished to do so, subject to the following conditions:
|
|
Packit |
130fc8 |
*
|
|
Packit |
130fc8 |
* The above copyright notice and this permission notice shall be
|
|
Packit |
130fc8 |
* included in all copies or substantial portions of the Software.
|
|
Packit |
130fc8 |
*
|
|
Packit |
130fc8 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
Packit |
130fc8 |
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
Packit |
130fc8 |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
Packit |
130fc8 |
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
Packit |
130fc8 |
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
Packit |
130fc8 |
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
Packit |
130fc8 |
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
Packit |
130fc8 |
* DEALINGS IN THE SOFTWARE.
|
|
Packit |
130fc8 |
*/
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
#include "dbus_bindings-internal.h"
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
dbus_bool_t
|
|
Packit |
130fc8 |
dbus_py_validate_bus_name(const char *name,
|
|
Packit |
130fc8 |
dbus_bool_t may_be_unique,
|
|
Packit |
130fc8 |
dbus_bool_t may_be_not_unique)
|
|
Packit |
130fc8 |
{
|
|
Packit |
130fc8 |
dbus_bool_t dot = FALSE;
|
|
Packit |
130fc8 |
dbus_bool_t unique;
|
|
Packit |
130fc8 |
char last;
|
|
Packit |
130fc8 |
const char *ptr;
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
if (name[0] == '\0') {
|
|
Packit |
130fc8 |
PyErr_SetString(PyExc_ValueError, "Invalid bus name: "
|
|
Packit |
130fc8 |
"may not be empty");
|
|
Packit |
130fc8 |
return FALSE;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
unique = (name[0] == ':');
|
|
Packit |
130fc8 |
if (unique && !may_be_unique) {
|
|
Packit |
130fc8 |
PyErr_Format(PyExc_ValueError, "Invalid well-known bus name '%s':"
|
|
Packit |
130fc8 |
"only unique names may start with ':'", name);
|
|
Packit |
130fc8 |
return FALSE;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
if (!unique && !may_be_not_unique) {
|
|
Packit |
130fc8 |
PyErr_Format(PyExc_ValueError, "Invalid unique bus name '%s': "
|
|
Packit |
130fc8 |
"unique names must start with ':'", name);
|
|
Packit |
130fc8 |
return FALSE;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
if (strlen(name) > 255) {
|
|
Packit |
130fc8 |
PyErr_Format(PyExc_ValueError, "Invalid bus name '%s': "
|
|
Packit |
130fc8 |
"too long (> 255 characters)", name);
|
|
Packit |
130fc8 |
return FALSE;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
last = '\0';
|
|
Packit |
130fc8 |
for (ptr = name + (unique ? 1 : 0); *ptr; ptr++) {
|
|
Packit |
130fc8 |
if (*ptr == '.') {
|
|
Packit |
130fc8 |
dot = TRUE;
|
|
Packit |
130fc8 |
if (last == '.') {
|
|
Packit |
130fc8 |
PyErr_Format(PyExc_ValueError, "Invalid bus name '%s': "
|
|
Packit |
130fc8 |
"contains substring '..'", name);
|
|
Packit |
130fc8 |
return FALSE;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
else if (last == '\0') {
|
|
Packit |
130fc8 |
PyErr_Format(PyExc_ValueError, "Invalid bus name '%s': "
|
|
Packit |
130fc8 |
"must not start with '.'", name);
|
|
Packit |
130fc8 |
return FALSE;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
else if (*ptr >= '0' && *ptr <= '9') {
|
|
Packit |
130fc8 |
if (!unique) {
|
|
Packit |
130fc8 |
if (last == '.') {
|
|
Packit |
130fc8 |
PyErr_Format(PyExc_ValueError, "Invalid bus name '%s': "
|
|
Packit |
130fc8 |
"a digit may not follow '.' except in a "
|
|
Packit |
130fc8 |
"unique name starting with ':'", name);
|
|
Packit |
130fc8 |
return FALSE;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
else if (last == '\0') {
|
|
Packit |
130fc8 |
PyErr_Format(PyExc_ValueError, "Invalid bus name '%s': "
|
|
Packit |
130fc8 |
"must not start with a digit", name);
|
|
Packit |
130fc8 |
return FALSE;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
else if ((*ptr < 'a' || *ptr > 'z') &&
|
|
Packit |
130fc8 |
(*ptr < 'A' || *ptr > 'Z') && *ptr != '_' && *ptr != '-') {
|
|
Packit |
130fc8 |
PyErr_Format(PyExc_ValueError, "Invalid bus name '%s': "
|
|
Packit |
130fc8 |
"contains invalid character '%c'", name, *ptr);
|
|
Packit |
130fc8 |
return FALSE;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
last = *ptr;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
if (last == '.') {
|
|
Packit |
130fc8 |
PyErr_Format(PyExc_ValueError, "Invalid bus name '%s': must "
|
|
Packit |
130fc8 |
"not end with '.'", name);
|
|
Packit |
130fc8 |
return FALSE;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
if (!dot) {
|
|
Packit |
130fc8 |
PyErr_Format(PyExc_ValueError, "Invalid bus name '%s': must "
|
|
Packit |
130fc8 |
"contain '.'", name);
|
|
Packit |
130fc8 |
return FALSE;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
return TRUE;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
dbus_bool_t
|
|
Packit |
130fc8 |
dbus_py_validate_member_name(const char *name)
|
|
Packit |
130fc8 |
{
|
|
Packit |
130fc8 |
const char *ptr;
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
if (name[0] == '\0') {
|
|
Packit |
130fc8 |
PyErr_SetString(PyExc_ValueError, "Invalid member name: may not "
|
|
Packit |
130fc8 |
"be empty");
|
|
Packit |
130fc8 |
return FALSE;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
if (strlen(name) > 255) {
|
|
Packit |
130fc8 |
PyErr_Format(PyExc_ValueError, "Invalid member name '%s': "
|
|
Packit |
130fc8 |
"too long (> 255 characters)", name);
|
|
Packit |
130fc8 |
return FALSE;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
for (ptr = name; *ptr; ptr++) {
|
|
Packit |
130fc8 |
if (*ptr >= '0' && *ptr <= '9') {
|
|
Packit |
130fc8 |
if (ptr == name) {
|
|
Packit |
130fc8 |
PyErr_Format(PyExc_ValueError, "Invalid member name '%s': "
|
|
Packit |
130fc8 |
"must not start with a digit", name);
|
|
Packit |
130fc8 |
return FALSE;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
else if ((*ptr < 'a' || *ptr > 'z') &&
|
|
Packit |
130fc8 |
(*ptr < 'A' || *ptr > 'Z') && *ptr != '_') {
|
|
Packit |
130fc8 |
PyErr_Format(PyExc_ValueError, "Invalid member name '%s': "
|
|
Packit |
130fc8 |
"contains invalid character '%c'", name, *ptr);
|
|
Packit |
130fc8 |
return FALSE;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
return TRUE;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
dbus_bool_t
|
|
Packit |
130fc8 |
dbus_py_validate_interface_name(const char *name)
|
|
Packit |
130fc8 |
{
|
|
Packit |
130fc8 |
dbus_bool_t dot = FALSE;
|
|
Packit |
130fc8 |
char last;
|
|
Packit |
130fc8 |
const char *ptr;
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
if (name[0] == '\0') {
|
|
Packit |
130fc8 |
PyErr_SetString(PyExc_ValueError, "Invalid interface or error name: "
|
|
Packit |
130fc8 |
"may not be empty");
|
|
Packit |
130fc8 |
return FALSE;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
if (strlen(name) > 255) {
|
|
Packit |
130fc8 |
PyErr_Format(PyExc_ValueError, "Invalid interface or error name '%s': "
|
|
Packit |
130fc8 |
"too long (> 255 characters)", name);
|
|
Packit |
130fc8 |
return FALSE;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
last = '\0';
|
|
Packit |
130fc8 |
for (ptr = name; *ptr; ptr++) {
|
|
Packit |
130fc8 |
if (*ptr == '.') {
|
|
Packit |
130fc8 |
dot = TRUE;
|
|
Packit |
130fc8 |
if (last == '.') {
|
|
Packit |
130fc8 |
PyErr_Format(PyExc_ValueError, "Invalid interface or "
|
|
Packit |
130fc8 |
"error name '%s': contains substring '..'", name);
|
|
Packit |
130fc8 |
return FALSE;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
else if (last == '\0') {
|
|
Packit |
130fc8 |
PyErr_Format(PyExc_ValueError, "Invalid interface or error "
|
|
Packit |
130fc8 |
"name '%s': must not start with '.'", name);
|
|
Packit |
130fc8 |
return FALSE;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
else if (*ptr >= '0' && *ptr <= '9') {
|
|
Packit |
130fc8 |
if (last == '.') {
|
|
Packit |
130fc8 |
PyErr_Format(PyExc_ValueError, "Invalid interface or error "
|
|
Packit |
130fc8 |
"name '%s': a digit may not follow '.'", name);
|
|
Packit |
130fc8 |
return FALSE;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
else if (last == '\0') {
|
|
Packit |
130fc8 |
PyErr_Format(PyExc_ValueError, "Invalid interface or error "
|
|
Packit |
130fc8 |
"name '%s': must not start with a digit", name);
|
|
Packit |
130fc8 |
return FALSE;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
else if ((*ptr < 'a' || *ptr > 'z') &&
|
|
Packit |
130fc8 |
(*ptr < 'A' || *ptr > 'Z') && *ptr != '_') {
|
|
Packit |
130fc8 |
PyErr_Format(PyExc_ValueError, "Invalid interface or error "
|
|
Packit |
130fc8 |
"name '%s': contains invalid character '%c'",
|
|
Packit |
130fc8 |
name, *ptr);
|
|
Packit |
130fc8 |
return FALSE;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
last = *ptr;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
if (last == '.') {
|
|
Packit |
130fc8 |
PyErr_Format(PyExc_ValueError, "Invalid interface or error name "
|
|
Packit |
130fc8 |
"'%s': must not end with '.'", name);
|
|
Packit |
130fc8 |
return FALSE;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
if (!dot) {
|
|
Packit |
130fc8 |
PyErr_Format(PyExc_ValueError, "Invalid interface or error name "
|
|
Packit |
130fc8 |
"'%s': must contain '.'", name);
|
|
Packit |
130fc8 |
return FALSE;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
return TRUE;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
dbus_bool_t
|
|
Packit |
130fc8 |
dbus_py_validate_object_path(const char *path)
|
|
Packit |
130fc8 |
{
|
|
Packit |
130fc8 |
const char *ptr;
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
if (path[0] != '/') {
|
|
Packit |
130fc8 |
PyErr_Format(PyExc_ValueError, "Invalid object path '%s': does not "
|
|
Packit |
130fc8 |
"start with '/'", path);
|
|
Packit |
130fc8 |
return FALSE;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
if (path[1] == '\0') return TRUE;
|
|
Packit |
130fc8 |
for (ptr = path + 1; *ptr; ptr++) {
|
|
Packit |
130fc8 |
if (*ptr == '/') {
|
|
Packit |
130fc8 |
if (ptr[-1] == '/') {
|
|
Packit |
130fc8 |
PyErr_Format(PyExc_ValueError, "Invalid object path '%s': "
|
|
Packit |
130fc8 |
"contains substring '//'", path);
|
|
Packit |
130fc8 |
return FALSE;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
else if ((*ptr < 'a' || *ptr > 'z') &&
|
|
Packit |
130fc8 |
(*ptr < 'A' || *ptr > 'Z') &&
|
|
Packit |
130fc8 |
(*ptr < '0' || *ptr > '9') && *ptr != '_') {
|
|
Packit |
130fc8 |
PyErr_Format(PyExc_ValueError, "Invalid object path '%s': "
|
|
Packit |
130fc8 |
"contains invalid character '%c'", path, *ptr);
|
|
Packit |
130fc8 |
return FALSE;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
if (ptr[-1] == '/') {
|
|
Packit |
130fc8 |
PyErr_Format(PyExc_ValueError, "Invalid object path '%s': ends "
|
|
Packit |
130fc8 |
"with '/' and is not just '/'", path);
|
|
Packit |
130fc8 |
return FALSE;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
return TRUE;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
/* vim:set ft=c cino< sw=4 sts=4 et: */
|