Hi Tristan,
I have not seen that behaviour, I would suggest stepping through the daemon with gdb and providing a backtrace when the daemon gets kicked from the session.
We found the source of the bug yesterday. The second INVITE contains a `display-name` made of invalid characters. In this instance, `display-name` starts with 0xb1, which is invalid in utf-8.
It seems like sflphoned does not verify that the `display-name` is valid before sending it to the GUI through dbus.
I have created and attached a sipp test that simulates this case. You can run this test with the following command:
$ sipp -sf bad-display-name.xml -inf character.txt -m 1 remote-host:[remote-port]
For the time being, our temporary fix is to patch `sip_utils.cpp` to check for a valid `display-name`. I know that this is not a solid fix, but I'm providing it here so you can see one functional workaround.
Cheers, Pascal Potvin Software Developer [email protected] Extenway Solutions Inc. 514-694-1916 x290
bad-display-name-sipp-test.tar.gz
Description: application/gzip
diff --git a/daemon/src/sip/sip_utils.cpp b/daemon/src/sip/sip_utils.cpp
index 48df5f4..5226ee2 100644
--- daemon.orig/src/sip/sip_utils.cpp
+++ daemon/src/sip/sip_utils.cpp
@@ -50,6 +50,87 @@
#include <vector>
#include <algorithm>
+bool
+is_utf8(const char * string)
+{
+ if(!string)
+ return false;
+
+ const unsigned char * bytes = (const unsigned char *)string;
+ while(*bytes)
+ {
+ if( (// ASCII
+ // use bytes[0] <= 0x7F to allow ASCII control characters
+ bytes[0] == 0x09 ||
+ bytes[0] == 0x0A ||
+ bytes[0] == 0x0D ||
+ (0x20 <= bytes[0] && bytes[0] <= 0x7E)
+ )
+ ) {
+ bytes += 1;
+ continue;
+ }
+
+ if( (// non-overlong 2-byte
+ (0xC2 <= bytes[0] && bytes[0] <= 0xDF) &&
+ (0x80 <= bytes[1] && bytes[1] <= 0xBF)
+ )
+ ) {
+ bytes += 2;
+ continue;
+ }
+
+ if( (// excluding overlongs
+ bytes[0] == 0xE0 &&
+ (0xA0 <= bytes[1] && bytes[1] <= 0xBF) &&
+ (0x80 <= bytes[2] && bytes[2] <= 0xBF)
+ ) ||
+ (// straight 3-byte
+ ((0xE1 <= bytes[0] && bytes[0] <= 0xEC) ||
+ bytes[0] == 0xEE ||
+ bytes[0] == 0xEF) &&
+ (0x80 <= bytes[1] && bytes[1] <= 0xBF) &&
+ (0x80 <= bytes[2] && bytes[2] <= 0xBF)
+ ) ||
+ (// excluding surrogates
+ bytes[0] == 0xED &&
+ (0x80 <= bytes[1] && bytes[1] <= 0x9F) &&
+ (0x80 <= bytes[2] && bytes[2] <= 0xBF)
+ )
+ ) {
+ bytes += 3;
+ continue;
+ }
+
+ if( (// planes 1-3
+ bytes[0] == 0xF0 &&
+ (0x90 <= bytes[1] && bytes[1] <= 0xBF) &&
+ (0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
+ (0x80 <= bytes[3] && bytes[3] <= 0xBF)
+ ) ||
+ (// planes 4-15
+ (0xF1 <= bytes[0] && bytes[0] <= 0xF3) &&
+ (0x80 <= bytes[1] && bytes[1] <= 0xBF) &&
+ (0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
+ (0x80 <= bytes[3] && bytes[3] <= 0xBF)
+ ) ||
+ (// plane 16
+ bytes[0] == 0xF4 &&
+ (0x80 <= bytes[1] && bytes[1] <= 0x8F) &&
+ (0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
+ (0x80 <= bytes[3] && bytes[3] <= 0xBF)
+ )
+ ) {
+ bytes += 4;
+ continue;
+ }
+
+ return false;
+ }
+
+ return true;
+}
+
std::string
sip_utils::fetchHeaderValue(pjsip_msg *msg, const std::string &field)
{
@@ -137,6 +218,9 @@ sip_utils::parseDisplayName(const char * buffer)
std::string displayName = temp.substr(begin_displayName + 1,
end_displayName - begin_displayName - 1);
+ if (!is_utf8(displayName.c_str()))
+ return "";
+
static const size_t MAX_DISPLAY_NAME_SIZE = 25;
if (displayName.size() > MAX_DISPLAY_NAME_SIZE)
return displayName.substr(0, MAX_DISPLAY_NAME_SIZE);
_______________________________________________ SFLphone mailing list [email protected] http://lists.savoirfairelinux.net/mailman/listinfo/sflphone
