[Xmpp] Latin-1 space characters are not forbidden for XMPP resources
Also use mb_strlen() with the 8bit encoding to count octets, strlen() is not as reliable (mbstring.func_overload).
This commit is contained in:
parent
05f4b1e97d
commit
0bbcb5b098
@ -114,38 +114,48 @@ class XmppPlugin extends ImPlugin
|
||||
*/
|
||||
protected function splitJid($jid)
|
||||
{
|
||||
$chars = '';
|
||||
$chars = [];
|
||||
/* the following definitions come from stringprep, Appendix C,
|
||||
which is used in its entirety by nodeprop, Chapter 5, "Prohibited Output" */
|
||||
/* C1.1 ASCII space characters */
|
||||
$chars .= "\x{20}";
|
||||
/* C1.2 Non-ASCII space characters */
|
||||
$chars .= "\x{a0}\x{1680}\x{2000}-\x{200b}\x{202f}\x{205f}\x{3000a}";
|
||||
/* C2.1 ASCII control characters */
|
||||
$chars .= "\x{00}-\x{1f}\x{7f}";
|
||||
/* C2.2 Non-ASCII control characters */
|
||||
$chars .= "\x{80}-\x{9f}\x{6dd}\x{70f}\x{180e}\x{200c}\x{200d}\x{2028}\x{2029}\x{2060}-\x{2063}\x{206a}-\x{206f}\x{feff}\x{fff9}-\x{fffc}\x{1d173}-\x{1d17a}";
|
||||
/* C3 - Private Use */
|
||||
$chars .= "\x{e000}-\x{f8ff}\x{f0000}-\x{ffffd}\x{100000}-\x{10fffd}";
|
||||
/* C4 - Non-character code points */
|
||||
$chars .= "\x{fdd0}-\x{fdef}\x{fffe}\x{ffff}\x{1fffe}\x{1ffff}\x{2fffe}\x{2ffff}\x{3fffe}\x{3ffff}\x{4fffe}\x{4ffff}\x{5fffe}\x{5ffff}\x{6fffe}\x{6ffff}\x{7fffe}\x{7ffff}\x{8fffe}\x{8ffff}\x{9fffe}\x{9ffff}\x{afffe}\x{affff}\x{bfffe}\x{bffff}\x{cfffe}\x{cffff}\x{dfffe}\x{dffff}\x{efffe}\x{effff}\x{ffffe}\x{fffff}\x{10fffe}\x{10ffff}";
|
||||
/* C5 - Surrogate codes */
|
||||
// C.1.1 Latin-1 space characters
|
||||
$chars['1.1'] = "\x{20}";
|
||||
// C.1.2 Non-Latin-1 space characters
|
||||
$chars['1.2'] = "\x{a0}\x{1680}\x{2000}-\x{200b}\x{202f}\x{205f}\x{3000a}";
|
||||
// C.2.1 Latin-1 control characters
|
||||
$chars['2.1'] = "\x{00}-\x{1f}\x{7f}";
|
||||
// C.2.2 Non-Latin-1 control characters
|
||||
$chars['2.2'] = "\x{80}-\x{9f}\x{6dd}\x{70f}\x{180e}\x{200c}\x{200d}"
|
||||
. "\x{2028}\x{2029}\x{2060}-\x{2063}\x{206a}-\x{206f}\x{feff}"
|
||||
. "\x{fff9}-\x{fffc}\x{1d173}-\x{1d17a}";
|
||||
// C.3 - Private Use
|
||||
$chars['3'] = "\x{e000}-\x{f8ff}\x{f0000}-\x{ffffd}\x{100000}-\x{10fffd}";
|
||||
// C.4 - Non-character code points
|
||||
$chars['4'] = "\x{fdd0}-\x{fdef}\x{fffe}\x{ffff}\x{1fffe}\x{1ffff}"
|
||||
. "\x{2fffe}\x{2ffff}\x{3fffe}\x{3ffff}\x{4fffe}\x{4ffff}\x{5fffe}"
|
||||
. "\x{5ffff}\x{6fffe}\x{6ffff}\x{7fffe}\x{7ffff}\x{8fffe}\x{8ffff}"
|
||||
. "\x{9fffe}\x{9ffff}\x{afffe}\x{affff}\x{bfffe}\x{bffff}\x{cfffe}"
|
||||
. "\x{cffff}\x{dfffe}\x{dffff}\x{efffe}\x{effff}\x{ffffe}\x{fffff}"
|
||||
. "\x{10fffe}\x{10ffff}";
|
||||
// C.5 - Surrogate codes
|
||||
// We can't use preg_match to check this, fix below
|
||||
// $chars .= "\x{d800}-\x{dfff}";
|
||||
/* C6 - Inappropriate for plain text */
|
||||
$chars .= "\x{fff9}-\x{fffd}";
|
||||
/* C7 - Inappropriate for canonical representation */
|
||||
$chars .= "\x{2ff0}-\x{2ffb}";
|
||||
/* C8 - Change display properties or are deprecated */
|
||||
$chars .= "\x{340}\x{341}\x{200e}\x{200f}\x{202a}-\x{202e}\x{206a}-\x{206f}";
|
||||
/* C9 - Tagging characters */
|
||||
$chars .= "\x{e0001}\x{e0020}-\x{e007f}";
|
||||
// $chars['5'] = "\x{d800}-\x{dfff}";
|
||||
// C.6 - Inappropriate for plain text
|
||||
$chars['6'] = "\x{fff9}-\x{fffd}";
|
||||
// C.7 - Inappropriate for canonical representation
|
||||
$chars['7'] = "\x{2ff0}-\x{2ffb}";
|
||||
// C.8 - Change display properties or are deprecated
|
||||
$chars['8'] = "\x{340}\x{341}\x{200e}\x{200f}\x{202a}-\x{202e}\x{206a}-\x{206f}";
|
||||
// C.9 - Tagging characters
|
||||
$chars['9'] = "\x{e0001}\x{e0020}-\x{e007f}";
|
||||
|
||||
/* Nodeprep forbids some more characters */
|
||||
$nodeprepchars = $chars;
|
||||
$nodeprepchars .= "\x{22}\x{26}\x{27}\x{2f}\x{3a}\x{3c}\x{3e}\x{40}";
|
||||
$nodeprep_chars = implode('', $chars);
|
||||
// Nodeprep forbids some more characters
|
||||
$nodeprep_chars .= "\x{22}\x{26}\x{27}\x{2f}\x{3a}\x{3c}\x{3e}\x{40}";
|
||||
|
||||
$parts = explode("/", $jid, 2);
|
||||
// Resourceprep forbids all from stringprep, Appendix C, except for C.1.1
|
||||
$resprep_chars = implode('', array_slice($chars, 1));
|
||||
|
||||
$parts = explode('/', $jid, 2);
|
||||
if (count($parts) > 1) {
|
||||
$resource = $parts[1];
|
||||
// if ($resource == '') then
|
||||
@ -171,21 +181,22 @@ class XmppPlugin extends ImPlugin
|
||||
}
|
||||
}
|
||||
|
||||
if ($node !== null) {
|
||||
// Length limits per http://xmpp.org/rfcs/rfc3920.html#addressing
|
||||
if (strlen($node) > 1023) {
|
||||
if (!is_null($node)) {
|
||||
// Length limits per https://xmpp.org/rfcs/rfc3920.html#addressing
|
||||
if (mb_strlen($node, '8bit') > 1023) {
|
||||
// TRANS: Exception thrown when using too long a Jabber ID (>1023).
|
||||
throw new UnexpectedValueException(_m('Invalid JID: node too long.'));
|
||||
}
|
||||
// C5 - Surrogate codes is ensured by encoding check
|
||||
if (preg_match("/[" . $nodeprepchars . "]/u", $node) || mb_detect_encoding($node, 'UTF-8', true) != 'UTF-8') {
|
||||
if (preg_match("/[{$nodeprep_chars}]/u", $node)
|
||||
|| mb_detect_encoding($node, 'UTF-8', true) !== 'UTF-8') {
|
||||
// TRANS: Exception thrown when using an invalid Jabber ID.
|
||||
// TRANS: %s is the invalid Jabber ID.
|
||||
throw new UnexpectedValueException(sprintf(_m('Invalid JID node "%s".'), $node));
|
||||
}
|
||||
}
|
||||
|
||||
if (strlen($domain) > 1023) {
|
||||
if (mb_strlen($domain, '8bit') > 1023) {
|
||||
// TRANS: Exception thrown when using too long a Jabber domain (>1023).
|
||||
throw new UnexpectedValueException(_m('Invalid JID: domain too long.'));
|
||||
}
|
||||
@ -195,12 +206,12 @@ class XmppPlugin extends ImPlugin
|
||||
throw new UnexpectedValueException(sprintf(_m('Invalid JID domain name "%s".'), $domain));
|
||||
}
|
||||
|
||||
if ($resource !== null) {
|
||||
if (strlen($resource) > 1023) {
|
||||
if (!is_null($resource)) {
|
||||
if (mb_strlen($resource, '8bit') > 1023) {
|
||||
// TRANS: Exception thrown when using too long a resource (>1023).
|
||||
throw new UnexpectedValueException('Invalid JID: resource too long.');
|
||||
}
|
||||
if (preg_match("/[" . $chars . "]/u", $resource)) {
|
||||
if (preg_match("/[{$resprep_chars}]/u", $resource)) {
|
||||
// TRANS: Exception thrown when using an invalid Jabber resource.
|
||||
// TRANS: %s is the invalid resource.
|
||||
throw new UnexpectedValueException(sprintf(_m('Invalid JID resource "%s".'), $resource));
|
||||
@ -346,7 +357,12 @@ class XmppPlugin extends ImPlugin
|
||||
{
|
||||
$from = $this->normalize($pl['from']);
|
||||
|
||||
if ($pl['type'] != 'chat') {
|
||||
if (is_null($from)) {
|
||||
$this->log(LOG_WARNING, 'Ignoring message from invalid JID: ' . $pl['xml']->toString());
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($pl['type'] !== 'chat') {
|
||||
$this->log(LOG_WARNING, "Ignoring message of type " . $pl['type'] . " from $from: " . $pl['xml']->toString());
|
||||
return true;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user