diff options
author | Anas Nashif <anas.nashif@intel.com> | 2012-10-30 16:38:35 -0700 |
---|---|---|
committer | Anas Nashif <anas.nashif@intel.com> | 2012-10-30 16:38:35 -0700 |
commit | 84a74d5225e520b3f32ec1d37b7b4a5ed040b66a (patch) | |
tree | a054332610562cedcd9f72862fbb22522844b70f /_dbus_bindings/message-append.c | |
parent | bacb91163539eca0a185298b620db7cf74660411 (diff) | |
download | dbus-python-84a74d5225e520b3f32ec1d37b7b4a5ed040b66a.tar.gz dbus-python-84a74d5225e520b3f32ec1d37b7b4a5ed040b66a.tar.bz2 dbus-python-84a74d5225e520b3f32ec1d37b7b4a5ed040b66a.zip |
Imported Upstream version 1.1.1upstream/1.1.1
Diffstat (limited to '_dbus_bindings/message-append.c')
-rw-r--r-- | _dbus_bindings/message-append.c | 172 |
1 files changed, 109 insertions, 63 deletions
diff --git a/_dbus_bindings/message-append.c b/_dbus_bindings/message-append.c index 6dab214..e519ae2 100644 --- a/_dbus_bindings/message-append.c +++ b/_dbus_bindings/message-append.c @@ -29,6 +29,7 @@ #include <assert.h> #define DBG_IS_TOO_VERBOSE +#include "compat-internal.h" #include "types-internal.h" #include "message-internal.h" @@ -248,8 +249,16 @@ _signature_string_from_pyobject(PyObject *obj, long *variant_level_ptr) return NATIVESTR_FROMSTR(DBUS_TYPE_INT64_AS_STRING); } #endif /* PY3 */ - else if (PyUnicode_Check(obj)) - return NATIVESTR_FROMSTR(DBUS_TYPE_STRING_AS_STRING); + else if (PyUnicode_Check(obj)) { + /* Object paths and signatures are unicode subtypes in Python 3 + * (the first two cases will never be true in Python 2) */ + if (DBusPyObjectPath_Check(obj)) + return NATIVESTR_FROMSTR(DBUS_TYPE_OBJECT_PATH_AS_STRING); + else if (DBusPySignature_Check(obj)) + return NATIVESTR_FROMSTR(DBUS_TYPE_SIGNATURE_AS_STRING); + else + return NATIVESTR_FROMSTR(DBUS_TYPE_STRING_AS_STRING); + } #if defined(DBUS_TYPE_UNIX_FD) else if (DBusPyUnixFd_Check(obj)) return NATIVESTR_FROMSTR(DBUS_TYPE_UNIX_FD_AS_STRING); @@ -265,6 +274,8 @@ _signature_string_from_pyobject(PyObject *obj, long *variant_level_ptr) return NATIVESTR_FROMSTR(DBUS_TYPE_DOUBLE_AS_STRING); } else if (PyBytes_Check(obj)) { + /* Object paths and signatures are bytes subtypes in Python 2 + * (the first two cases will never be true in Python 3) */ if (DBusPyObjectPath_Check(obj)) return NATIVESTR_FROMSTR(DBUS_TYPE_OBJECT_PATH_AS_STRING); else if (DBusPySignature_Check(obj)) @@ -520,6 +531,7 @@ _message_iter_append_string(DBusMessageIter *appender, dbus_bool_t allow_object_path_attr) { char *s; + PyObject *utf8; if (sig_type == DBUS_TYPE_OBJECT_PATH && allow_object_path_attr) { PyObject *object_path = get_object_path (obj); @@ -539,44 +551,87 @@ _message_iter_append_string(DBusMessageIter *appender, } if (PyBytes_Check(obj)) { - PyObject *unicode; - - /* Raise TypeError if the string has embedded NULs */ - if (PyBytes_AsStringAndSize(obj, &s, NULL) < 0) return -1; - /* Surely there's a faster stdlib way to validate UTF-8... */ - unicode = PyUnicode_DecodeUTF8(s, PyBytes_GET_SIZE(obj), NULL); - if (!unicode) { - PyErr_SetString(PyExc_UnicodeError, "String parameters " - "to be sent over D-Bus must be valid UTF-8"); - return -1; - } - Py_CLEAR(unicode); - - DBG("Performing actual append: string %s", s); - if (!dbus_message_iter_append_basic(appender, sig_type, - &s)) { - PyErr_NoMemory(); - return -1; - } + utf8 = obj; + Py_INCREF(obj); } else if (PyUnicode_Check(obj)) { - PyObject *utf8 = PyUnicode_AsUTF8String(obj); + utf8 = PyUnicode_AsUTF8String(obj); if (!utf8) return -1; - /* Raise TypeError if the string has embedded NULs */ - if (PyBytes_AsStringAndSize(utf8, &s, NULL) < 0) return -1; - DBG("Performing actual append: string (from unicode) %s", s); - if (!dbus_message_iter_append_basic(appender, sig_type, &s)) { - Py_CLEAR(utf8); - PyErr_NoMemory(); - return -1; - } - Py_CLEAR(utf8); } else { PyErr_SetString(PyExc_TypeError, "Expected a string or unicode object"); return -1; } + + /* Raise TypeError if the string has embedded NULs */ + if (PyBytes_AsStringAndSize(utf8, &s, NULL) < 0) + return -1; + + /* Validate UTF-8, strictly */ +#ifdef HAVE_DBUS_VALIDATE_UTF8 + if (!dbus_validate_utf8(s, NULL)) { + PyErr_SetString(PyExc_UnicodeError, "String parameters " + "to be sent over D-Bus must be valid UTF-8 " + "with no noncharacter code points"); + return -1; + } +#else + { + PyObject *back_to_unicode; + PyObject *utf32; + Py_ssize_t i; + + /* This checks for syntactically valid UTF-8, but does not check + * for noncharacters (U+nFFFE, U+nFFFF for any n, or U+FDD0..U+FDEF). + */ + back_to_unicode = PyUnicode_DecodeUTF8(s, PyBytes_GET_SIZE(utf8), + "strict"); + + if (!back_to_unicode) { + return -1; + } + + utf32 = PyUnicode_AsUTF32String(back_to_unicode); + Py_CLEAR(back_to_unicode); + + if (!utf32) { + return -1; + } + + for (i = 0; i < PyBytes_GET_SIZE(utf32) / 4; i++) { + dbus_uint32_t *p; + + p = (dbus_uint32_t *) (PyBytes_AS_STRING(utf32)) + i; + + if (/* noncharacters U+nFFFE, U+nFFFF */ + (*p & 0xFFFF) == 0xFFFE || + (*p & 0xFFFF) == 0xFFFF || + /* noncharacters U+FDD0..U+FDEF */ + (*p >= 0xFDD0 && *p <= 0xFDEF) || + /* surrogates U+D800..U+DBFF (low), U+DC00..U+DFFF (high) */ + (*p >= 0xD800 && *p <= 0xDFFF) || + (*p >= 0x110000)) { + Py_CLEAR(utf32); + PyErr_SetString(PyExc_UnicodeError, "String parameters " + "to be sent over D-Bus must be valid UTF-8 " + "with no noncharacter code points"); + return -1; + } + } + + Py_CLEAR(utf32); + } +#endif + + DBG("Performing actual append: string (from unicode) %s", s); + if (!dbus_message_iter_append_basic(appender, sig_type, &s)) { + Py_CLEAR(utf8); + PyErr_NoMemory(); + return -1; + } + + Py_CLEAR(utf8); return 0; } @@ -999,18 +1054,7 @@ _message_iter_append_pyobject(DBusMessageIter *appender, dbus_bool_t *more) { int sig_type = dbus_signature_iter_get_current_type(sig_iter); - union { - dbus_bool_t b; - double d; - dbus_uint16_t uint16; - dbus_int16_t int16; - dbus_uint32_t uint32; - dbus_int32_t int32; -#if defined(DBUS_HAVE_INT64) && defined(HAVE_LONG_LONG) - dbus_uint64_t uint64; - dbus_int64_t int64; -#endif - } u; + DBusBasicValue u; int ret = -1; #ifdef USING_DBG @@ -1026,13 +1070,13 @@ _message_iter_append_pyobject(DBusMessageIter *appender, case DBUS_TYPE_BOOLEAN: if (PyObject_IsTrue(obj)) { - u.b = 1; + u.bool_val = 1; } else { - u.b = 0; + u.bool_val = 0; } - DBG("Performing actual append: bool(%ld)", (long)u.b); - if (!dbus_message_iter_append_basic(appender, sig_type, &u.b)) { + DBG("Performing actual append: bool(%ld)", (long)u.bool_val); + if (!dbus_message_iter_append_basic(appender, sig_type, &u.bool_val)) { PyErr_NoMemory(); ret = -1; break; @@ -1041,13 +1085,13 @@ _message_iter_append_pyobject(DBusMessageIter *appender, break; case DBUS_TYPE_DOUBLE: - u.d = PyFloat_AsDouble(obj); + u.dbl = PyFloat_AsDouble(obj); if (PyErr_Occurred()) { ret = -1; break; } - DBG("Performing actual append: double(%f)", u.d); - if (!dbus_message_iter_append_basic(appender, sig_type, &u.d)) { + DBG("Performing actual append: double(%f)", u.dbl); + if (!dbus_message_iter_append_basic(appender, sig_type, &u.dbl)) { PyErr_NoMemory(); ret = -1; break; @@ -1057,12 +1101,14 @@ _message_iter_append_pyobject(DBusMessageIter *appender, #ifdef WITH_DBUS_FLOAT32 case DBUS_TYPE_FLOAT: - u.d = PyFloat_AsDouble(obj); + u.dbl = PyFloat_AsDouble(obj); if (PyErr_Occurred()) { ret = -1; break; } - u.f = (float)u.d; + /* FIXME: DBusBasicValue will need to grow a float member if + * float32 becomes supported */ + u.f = (float)u.dbl; DBG("Performing actual append: float(%f)", u.f); if (!dbus_message_iter_append_basic(appender, sig_type, &u.f)) { PyErr_NoMemory(); @@ -1075,14 +1121,14 @@ _message_iter_append_pyobject(DBusMessageIter *appender, /* The integer types are all basically the same - we delegate to intNN_range_check() */ -#define PROCESS_INTEGER(size) \ - u.size = dbus_py_##size##_range_check(obj);\ - if (u.size == (dbus_##size##_t)(-1) && PyErr_Occurred()) {\ +#define PROCESS_INTEGER(size, member) \ + u.member = dbus_py_##size##_range_check(obj);\ + if (u.member == (dbus_##size##_t)(-1) && PyErr_Occurred()) {\ ret = -1; \ break; \ }\ - DBG("Performing actual append: " #size "(%lld)", (long long)u.size); \ - if (!dbus_message_iter_append_basic(appender, sig_type, &u.size)) {\ + DBG("Performing actual append: " #size "(%lld)", (long long)u.member); \ + if (!dbus_message_iter_append_basic(appender, sig_type, &u.member)) {\ PyErr_NoMemory();\ ret = -1;\ break;\ @@ -1090,23 +1136,23 @@ _message_iter_append_pyobject(DBusMessageIter *appender, ret = 0; case DBUS_TYPE_INT16: - PROCESS_INTEGER(int16) + PROCESS_INTEGER(int16, i16) break; case DBUS_TYPE_UINT16: - PROCESS_INTEGER(uint16) + PROCESS_INTEGER(uint16, u16) break; case DBUS_TYPE_INT32: - PROCESS_INTEGER(int32) + PROCESS_INTEGER(int32, i32) break; case DBUS_TYPE_UINT32: - PROCESS_INTEGER(uint32) + PROCESS_INTEGER(uint32, u32) break; #if defined(DBUS_HAVE_INT64) && defined(HAVE_LONG_LONG) case DBUS_TYPE_INT64: - PROCESS_INTEGER(int64) + PROCESS_INTEGER(int64, i64) break; case DBUS_TYPE_UINT64: - PROCESS_INTEGER(uint64) + PROCESS_INTEGER(uint64, u64) break; #else case DBUS_TYPE_INT64: |