Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-slixmpp for openSUSE:Factory 
checked in at 2022-12-07 17:34:58
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-slixmpp (Old)
 and      /work/SRC/openSUSE:Factory/.python-slixmpp.new.1835 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-slixmpp"

Wed Dec  7 17:34:58 2022 rev:10 rq:1040751 version:1.8.3

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-slixmpp/python-slixmpp.changes    
2022-10-29 20:19:03.722835727 +0200
+++ /work/SRC/openSUSE:Factory/.python-slixmpp.new.1835/python-slixmpp.changes  
2022-12-07 17:36:17.444974678 +0100
@@ -1,0 +2,6 @@
+Tue Dec  6 15:35:51 UTC 2022 - Michael Vetter <mvet...@suse.com>
+
+- bsc#1205433 Update to 1.8.3:
+  * Fix CVE-2022-45197: missing certificate hostname validation
+
+-------------------------------------------------------------------

Old:
----
  slixmpp-slix-1.8.2.tar.bz2

New:
----
  slixmpp-slix-1.8.3.tar.bz2

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-slixmpp.spec ++++++
--- /var/tmp/diff_new_pack.jw88mk/_old  2022-12-07 17:36:17.936977371 +0100
+++ /var/tmp/diff_new_pack.jw88mk/_new  2022-12-07 17:36:17.940977393 +0100
@@ -20,7 +20,7 @@
 %define skip_python36 1
 %define _name   slixmpp
 Name:           python-slixmpp
-Version:        1.8.2
+Version:        1.8.3
 Release:        0
 Summary:        Python XMPP (Jabber) Library that Implements Everything as a 
Plugin
 License:        MIT

++++++ slixmpp-slix-1.8.2.tar.bz2 -> slixmpp-slix-1.8.3.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/slixmpp-slix-1.8.2/doap.xml 
new/slixmpp-slix-1.8.3/doap.xml
--- old/slixmpp-slix-1.8.2/doap.xml     2022-04-06 22:44:40.000000000 +0200
+++ new/slixmpp-slix-1.8.3/doap.xml     2022-11-12 21:39:50.000000000 +0100
@@ -457,6 +457,14 @@
     </implements>
     <implements>
         <xmpp:SupportedXep>
+            <xmpp:xep 
rdf:resource="https://xmpp.org/extensions/xep-0175.html"/>
+            <xmpp:status>complete</xmpp:status>
+            <xmpp:version>1.2</xmpp:version>
+            <xmpp:since>1.0</xmpp:since>
+        </xmpp:SupportedXep>
+    </implements>
+    <implements>
+        <xmpp:SupportedXep>
             <xmpp:xep 
rdf:resource="https://xmpp.org/extensions/xep-0184.html"/>
             <xmpp:status>complete</xmpp:status>
             <xmpp:version>1.4.0</xmpp:version>
@@ -1041,5 +1049,12 @@
             <file-release 
rdf:resource="https://lab.louiz.org/poezio/slixmpp/-/archive/slix-1.8.2/slixmpp-slix-1.8.2.tar.gz"/>
         </Version>
     </release>
+    <release>
+        <Version>
+            <revision>1.8.3</revision>
+            <created>2022-11-12</created>
+            <file-release 
rdf:resource="https://lab.louiz.org/poezio/slixmpp/-/archive/slix-1.8.3/slixmpp-slix-1.8.3.tar.gz"/>
+        </Version>
+    </release>
 </Project>
 </rdf:RDF>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/slixmpp-slix-1.8.2/docs/api/plugins/xep_0055.rst 
new/slixmpp-slix-1.8.3/docs/api/plugins/xep_0055.rst
--- old/slixmpp-slix-1.8.2/docs/api/plugins/xep_0055.rst        1970-01-01 
01:00:00.000000000 +0100
+++ new/slixmpp-slix-1.8.3/docs/api/plugins/xep_0055.rst        2022-11-12 
21:39:50.000000000 +0100
@@ -0,0 +1,18 @@
+
+XEP-0055: Jabber search
+=======================
+
+.. module:: slixmpp.plugins.xep_0055
+
+.. autoclass:: XEP_0055
+    :members:
+    :exclude-members: session_bind, plugin_init, plugin_end
+
+
+Stanza elements
+---------------
+
+.. automodule:: slixmpp.plugins.xep_0055.stanza
+    :members:
+    :undoc-members:
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/slixmpp-slix-1.8.2/slixmpp/__init__.py 
new/slixmpp-slix-1.8.3/slixmpp/__init__.py
--- old/slixmpp-slix-1.8.2/slixmpp/__init__.py  2022-04-06 22:44:40.000000000 
+0200
+++ new/slixmpp-slix-1.8.3/slixmpp/__init__.py  2022-11-12 21:39:50.000000000 
+0100
@@ -5,7 +5,6 @@
 # See the file LICENSE for copying permission.
 import logging
 from os import getenv
-logging.getLogger(__name__).addHandler(logging.NullHandler())
 
 # Use defusedxml if wanted
 # Since enabling it can have adverse consequences for the programs using
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/slixmpp-slix-1.8.2/slixmpp/basexmpp.py 
new/slixmpp-slix-1.8.3/slixmpp/basexmpp.py
--- old/slixmpp-slix-1.8.2/slixmpp/basexmpp.py  2022-04-06 22:44:40.000000000 
+0200
+++ new/slixmpp-slix-1.8.3/slixmpp/basexmpp.py  2022-11-12 21:39:50.000000000 
+0100
@@ -140,7 +140,7 @@
         self.use_presence_ids = True
 
         #: XEP-0359 <origin-id/> tag that gets added to <message/> stanzas.
-        self.use_origin_id = True
+        self.use_origin_id = False
 
         #: The API registry is a way to process callbacks based on
         #: JID+node combinations. Each callback in the registry is
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/slixmpp-slix-1.8.2/slixmpp/jid.py 
new/slixmpp-slix-1.8.3/slixmpp/jid.py
--- old/slixmpp-slix-1.8.2/slixmpp/jid.py       2022-04-06 22:44:40.000000000 
+0200
+++ new/slixmpp-slix-1.8.3/slixmpp/jid.py       2022-11-12 21:39:50.000000000 
+0100
@@ -368,7 +368,7 @@
         return self._node
 
     @node.setter
-    def node(self, value: str):
+    def node(self, value: Optional[str]):
         self._node = _validate_node(value)
         self._update_bare_full()
 
@@ -386,7 +386,7 @@
         return self._resource
 
     @resource.setter
-    def resource(self, value: str):
+    def resource(self, value: Optional[str]):
         self._resource = _validate_resource(value)
         self._update_bare_full()
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/slixmpp-slix-1.8.2/slixmpp/plugins/__init__.py 
new/slixmpp-slix-1.8.3/slixmpp/plugins/__init__.py
--- old/slixmpp-slix-1.8.2/slixmpp/plugins/__init__.py  2022-04-06 
22:44:40.000000000 +0200
+++ new/slixmpp-slix-1.8.3/slixmpp/plugins/__init__.py  2022-11-12 
21:39:50.000000000 +0100
@@ -1,4 +1,3 @@
-
 # Slixmpp: The Slick XMPP Library
 # Copyright (C) 2010 Nathanael C. Fritz
 # This file is part of Slixmpp.
@@ -24,6 +23,7 @@
     'xep_0049',  # Private XML Storage
     'xep_0050',  # Ad-hoc Commands
     'xep_0054',  # vcard-temp
+    'xep_0055',  # Jabber Search
     'xep_0059',  # Result Set Management
     'xep_0060',  # Pubsub (Client)
     'xep_0065',  # SOCKS5 Bytestreams
@@ -93,6 +93,7 @@
     'xep_0335',  # JSON Containers
     'xep_0352',  # Client State Indication
     'xep_0353',  # Jingle Message Initiation
+    'xep_0356',  # Privileged entity
     'xep_0359',  # Unique and Stable Stanza IDs
     'xep_0363',  # HTTP File Upload
     'xep_0369',  # MIX-CORE
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/slixmpp-slix-1.8.2/slixmpp/plugins/xep_0030/disco.py 
new/slixmpp-slix-1.8.3/slixmpp/plugins/xep_0030/disco.py
--- old/slixmpp-slix-1.8.2/slixmpp/plugins/xep_0030/disco.py    2022-04-06 
22:44:40.000000000 +0200
+++ new/slixmpp-slix-1.8.3/slixmpp/plugins/xep_0030/disco.py    2022-11-12 
21:39:50.000000000 +0100
@@ -385,6 +385,8 @@
                 local = True
 
         ifrom = kwargs.pop('ifrom', None)
+        if self.xmpp.is_component and ifrom is None:
+            ifrom = self.xmpp.boundjid
         if local:
             log.debug("Looking up local disco#info data "
                       "for %s, node %s.", jid, node)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/slixmpp-slix-1.8.2/slixmpp/plugins/xep_0045/muc.py 
new/slixmpp-slix-1.8.3/slixmpp/plugins/xep_0045/muc.py
--- old/slixmpp-slix-1.8.2/slixmpp/plugins/xep_0045/muc.py      2022-04-06 
22:44:40.000000000 +0200
+++ new/slixmpp-slix-1.8.3/slixmpp/plugins/xep_0045/muc.py      2022-11-12 
21:39:50.000000000 +0100
@@ -493,6 +493,8 @@
         """
         if affiliation not in AFFILIATIONS:
             raise ValueError('%s is not a valid affiliation' % affiliation)
+        if affiliation == 'outcast' and not jid:
+            raise ValueError('Outcast affiliation requires a using a jid')
         if not any((jid, nick)):
             raise ValueError('One of jid or nick must be set')
         iq = self.xmpp.make_iq_set(ito=room, ifrom=ifrom)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/slixmpp-slix-1.8.2/slixmpp/plugins/xep_0050/adhoc.py 
new/slixmpp-slix-1.8.3/slixmpp/plugins/xep_0050/adhoc.py
--- old/slixmpp-slix-1.8.2/slixmpp/plugins/xep_0050/adhoc.py    2022-04-06 
22:44:40.000000000 +0200
+++ new/slixmpp-slix-1.8.3/slixmpp/plugins/xep_0050/adhoc.py    2022-11-12 
21:39:50.000000000 +0100
@@ -620,6 +620,8 @@
 
 
 async def _await_if_needed(handler, *args):
+    if handler is None:
+        raise XMPPError("bad-request", text="The command is completed")
     if asyncio.iscoroutinefunction(handler):
         log.debug(f"%s is async", handler)
         return await handler(*args)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/slixmpp-slix-1.8.2/slixmpp/plugins/xep_0055/__init__.py 
new/slixmpp-slix-1.8.3/slixmpp/plugins/xep_0055/__init__.py
--- old/slixmpp-slix-1.8.2/slixmpp/plugins/xep_0055/__init__.py 1970-01-01 
01:00:00.000000000 +0100
+++ new/slixmpp-slix-1.8.3/slixmpp/plugins/xep_0055/__init__.py 2022-11-12 
21:39:50.000000000 +0100
@@ -0,0 +1,6 @@
+from slixmpp.plugins.base import register_plugin
+
+from .search import XEP_0055
+
+
+register_plugin(XEP_0055)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/slixmpp-slix-1.8.2/slixmpp/plugins/xep_0055/search.py 
new/slixmpp-slix-1.8.3/slixmpp/plugins/xep_0055/search.py
--- old/slixmpp-slix-1.8.2/slixmpp/plugins/xep_0055/search.py   1970-01-01 
01:00:00.000000000 +0100
+++ new/slixmpp-slix-1.8.3/slixmpp/plugins/xep_0055/search.py   2022-11-12 
21:39:50.000000000 +0100
@@ -0,0 +1,89 @@
+import logging
+
+from slixmpp import CoroutineCallback, StanzaPath, Iq, register_stanza_plugin
+from slixmpp.plugins import BasePlugin
+from slixmpp.xmlstream import StanzaBase
+
+from . import stanza
+
+
+class XEP_0055(BasePlugin):
+    """
+    XEP-0055: Jabber Search
+
+    The config options are only useful for a "server-side" search feature,
+    and if the ``provide_search`` option is set to True.
+
+    API
+    ===
+
+    ``search_get_form``: customize the search form content (ie fields)
+
+    ``search_query``: return search results
+    """
+    name = "xep_0055"
+    description = "XEP-0055: Jabber search"
+    dependencies = {"xep_0004", "xep_0030"}
+    stanza = stanza
+    default_config = {
+        "form_fields": {"first", "last"},
+        "form_instructions": "",
+        "form_title": "",
+        "provide_search": True
+    }
+
+    def plugin_init(self):
+        register_stanza_plugin(Iq, stanza.Search)
+        register_stanza_plugin(stanza.Search, 
self.xmpp["xep_0004"].stanza.Form)
+
+        if self.provide_search:
+            self.xmpp["xep_0030"].add_feature(stanza.Search.namespace)
+            self.xmpp.register_handler(
+                CoroutineCallback(
+                    "search",
+                    StanzaPath("/iq/search"),
+                    self._handle_search,
+                )
+            )
+            self.api.register(self._get_form, "search_get_form")
+            self.api.register(self._get_results, "search_query")
+
+    async def _handle_search(self, iq: StanzaBase):
+        if iq["search"]["form"].get_values():
+            reply = await self.api["search_query"](None, None, iq.get_from(), 
iq)
+            reply["search"]["form"]["type"] = "result"
+        else:
+            reply = await self.api["search_get_form"](None, None, 
iq.get_from(), iq)
+        reply["search"]["form"].add_field(
+            "FORM_TYPE", value=stanza.Search.namespace, ftype="hidden"
+        )
+        reply.send()
+
+    async def _get_form(self, jid, node, ifrom, iq):
+        reply = iq.reply()
+        form = reply["search"]["form"]
+        form["title"] = self.form_title
+        form["instructions"] = self.form_instructions
+        for field in self.form_fields:
+            form.add_field(field)
+        return reply
+
+    async def _get_results(self, jid, node, ifrom, iq):
+        reply = iq.reply()
+        form = reply["search"]["form"]
+        form["type"] = "result"
+
+        for field in self.form_fields:
+            form.add_reported(field)
+        return reply
+
+    def make_search_iq(self, **kwargs):
+        iq = self.xmpp.make_iq(itype="set", **kwargs)
+        iq["search"]["form"].set_type("submit")
+        iq["search"]["form"].add_field(
+            "FORM_TYPE", value=stanza.Search.namespace, ftype="hidden"
+        )
+        return iq
+
+
+log = logging.getLogger(__name__)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/slixmpp-slix-1.8.2/slixmpp/plugins/xep_0055/stanza.py 
new/slixmpp-slix-1.8.3/slixmpp/plugins/xep_0055/stanza.py
--- old/slixmpp-slix-1.8.2/slixmpp/plugins/xep_0055/stanza.py   1970-01-01 
01:00:00.000000000 +0100
+++ new/slixmpp-slix-1.8.3/slixmpp/plugins/xep_0055/stanza.py   2022-11-12 
21:39:50.000000000 +0100
@@ -0,0 +1,10 @@
+from typing import Set, ClassVar
+
+from slixmpp.xmlstream import ElementBase
+
+
+class Search(ElementBase):
+    namespace = "jabber:iq:search"
+    name = "query"
+    plugin_attrib = "search"
+    interfaces: ClassVar[Set[str]] = set()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/slixmpp-slix-1.8.2/slixmpp/plugins/xep_0082.py 
new/slixmpp-slix-1.8.3/slixmpp/plugins/xep_0082.py
--- old/slixmpp-slix-1.8.2/slixmpp/plugins/xep_0082.py  2022-04-06 
22:44:40.000000000 +0200
+++ new/slixmpp-slix-1.8.3/slixmpp/plugins/xep_0082.py  2022-11-12 
21:39:50.000000000 +0100
@@ -6,7 +6,6 @@
 import datetime as dt
 
 from slixmpp.plugins import BasePlugin, register_plugin
-from slixmpp.thirdparty import tzutc, tzoffset, parse_iso
 
 
 # =====================================================================
@@ -21,7 +20,10 @@
     Arguments:
         time_str -- A formatted timestamp string.
     """
-    return parse_iso(time_str)
+    try:
+        return dt.datetime.strptime(time_str, '%Y-%m-%dT%H:%M:%S.%f%z')
+    except ValueError:
+        return dt.datetime.strptime(time_str, '%Y-%m-%dT%H:%M:%S%z')
 
 
 def format_date(time_obj):
@@ -52,7 +54,7 @@
     if isinstance(time_obj, dt.datetime):
         time_obj = time_obj.timetz()
     timestamp = time_obj.isoformat()
-    if time_obj.tzinfo == tzutc():
+    if time_obj.tzinfo == dt.timezone.utc:
         timestamp = timestamp[:-6]
         return '%sZ' % timestamp
     return timestamp
@@ -69,7 +71,7 @@
         time_obj -- A datetime object.
     """
     timestamp = time_obj.isoformat('T')
-    if time_obj.tzinfo == tzutc():
+    if time_obj.tzinfo == dt.timezone.utc:
         timestamp = timestamp[:-6]
         return '%sZ' % timestamp
     return timestamp
@@ -128,9 +130,9 @@
     if micro is None:
         micro = now.microsecond
     if offset in (None, 0):
-        offset = tzutc()
+        offset = dt.timezone.utc
     elif not isinstance(offset, dt.tzinfo):
-        offset = tzoffset(None, offset)
+        offset = dt.timezone(dt.timedelta(seconds=offset))
     value = dt.time(hour, min, sec, micro, offset)
     if obj:
         return value
@@ -175,9 +177,9 @@
     if micro is None:
         micro = now.microsecond
     if offset in (None, 0):
-        offset = tzutc()
+        offset = dt.timezone.utc
     elif not isinstance(offset, dt.tzinfo):
-        offset = tzoffset(None, offset)
+        offset = dt.timezone(dt.timedelta(seconds=offset))
 
     value = dt.datetime(year, month, day, hour,
                        min, sec, micro, offset)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/slixmpp-slix-1.8.2/slixmpp/plugins/xep_0084/stanza.py 
new/slixmpp-slix-1.8.3/slixmpp/plugins/xep_0084/stanza.py
--- old/slixmpp-slix-1.8.2/slixmpp/plugins/xep_0084/stanza.py   2022-04-06 
22:44:40.000000000 +0200
+++ new/slixmpp-slix-1.8.3/slixmpp/plugins/xep_0084/stanza.py   2022-11-12 
21:39:50.000000000 +0100
@@ -80,16 +80,16 @@
         self._set_int('bytes', value)
 
     def get_height(self) -> int:
-        self._get_int('height')
+        return self._get_int('height')
 
     def set_height(self, value: int):
         self._set_int('height', value)
 
     def get_width(self) -> int:
-        self._get_int(self, 'width')
+        return self._get_int('width')
 
     def set_width(self, value: int):
-        self._set_int('with', value)
+        self._set_int('width', value)
 
 
 class Pointer(ElementBase):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/slixmpp-slix-1.8.2/slixmpp/plugins/xep_0115/static.py 
new/slixmpp-slix-1.8.3/slixmpp/plugins/xep_0115/static.py
--- old/slixmpp-slix-1.8.2/slixmpp/plugins/xep_0115/static.py   2022-04-06 
22:44:40.000000000 +0200
+++ new/slixmpp-slix-1.8.3/slixmpp/plugins/xep_0115/static.py   2022-11-12 
21:39:50.000000000 +0100
@@ -60,7 +60,7 @@
             return False
 
         if node in (None, ''):
-            info = self.caps.get_caps(jid)
+            info = await self.caps.get_caps(jid)
             if info and feature in info['features']:
                 return True
 
@@ -134,7 +134,7 @@
     def get_verstring(self, jid, node, ifrom, data):
         return self.jid_vers.get(jid, None)
 
-    def get_caps(self, jid, node, ifrom, data):
+    async def get_caps(self, jid, node, ifrom, data):
         verstring = data.get('verstring', None)
         if verstring is None:
             return None
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/slixmpp-slix-1.8.2/slixmpp/plugins/xep_0202/stanza.py 
new/slixmpp-slix-1.8.3/slixmpp/plugins/xep_0202/stanza.py
--- old/slixmpp-slix-1.8.2/slixmpp/plugins/xep_0202/stanza.py   2022-04-06 
22:44:40.000000000 +0200
+++ new/slixmpp-slix-1.8.3/slixmpp/plugins/xep_0202/stanza.py   2022-11-12 
21:39:50.000000000 +0100
@@ -8,7 +8,6 @@
 
 from slixmpp.xmlstream import ElementBase
 from slixmpp.plugins import xep_0082
-from slixmpp.thirdparty import tzutc, tzoffset
 
 
 class EntityTime(ElementBase):
@@ -87,7 +86,7 @@
                       seconds (positive or negative) to offset.
         """
         time = xep_0082.time(offset=value)
-        if xep_0082.parse(time).tzinfo == tzutc():
+        if xep_0082.parse(time).tzinfo == dt.timezone.utc:
             self._set_sub_text('tzo', 'Z')
         else:
             self._set_sub_text('tzo', time[-6:])
@@ -111,6 +110,6 @@
         date = value
         if not isinstance(value, dt.datetime):
             date = xep_0082.parse(value)
-        date = date.astimezone(tzutc())
+        date = date.astimezone(dt.timezone.utc)
         value = xep_0082.format_datetime(date)
         self._set_sub_text('utc', value)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/slixmpp-slix-1.8.2/slixmpp/plugins/xep_0203/stanza.py 
new/slixmpp-slix-1.8.3/slixmpp/plugins/xep_0203/stanza.py
--- old/slixmpp-slix-1.8.2/slixmpp/plugins/xep_0203/stanza.py   2022-04-06 
22:44:40.000000000 +0200
+++ new/slixmpp-slix-1.8.3/slixmpp/plugins/xep_0203/stanza.py   2022-11-12 
21:39:50.000000000 +0100
@@ -30,6 +30,10 @@
 
     def set_stamp(self, value):
         if isinstance(value, dt.datetime):
+            if value.tzinfo is None:
+                raise ValueError(f'Datetime provided without timezone 
information: {value}')
+            if value.tzinfo != dt.timezone.utc:
+                value = value.astimezone(dt.timezone.utc)
             value = xep_0082.format_datetime(value)
         self._set_attr('stamp', value)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/slixmpp-slix-1.8.2/slixmpp/plugins/xep_0333/markers.py 
new/slixmpp-slix-1.8.3/slixmpp/plugins/xep_0333/markers.py
--- old/slixmpp-slix-1.8.2/slixmpp/plugins/xep_0333/markers.py  2022-04-06 
22:44:40.000000000 +0200
+++ new/slixmpp-slix-1.8.3/slixmpp/plugins/xep_0333/markers.py  2022-11-12 
21:39:50.000000000 +0100
@@ -1,4 +1,3 @@
-
 # slixmpp: The Slick XMPP Library
 # Copyright (C) 2016 Emmanuel Gil Peyrot
 # This file is part of slixmpp.
@@ -68,11 +67,11 @@
         :param JID mto: recipient of the marker
         :param str id: Identifier of the marked message
         :param str marker: Marker to send (one of
-            displayed, retrieved, or acknowledged)
+            displayed, received, or acknowledged)
         :param str thread: Message thread
         :param str mfrom: Use a specific JID to send the message
         """
-        if marker not in ('displayed', 'retrieved', 'acknowledged'):
+        if marker not in ('displayed', 'received', 'acknowledged'):
             raise ValueError('Invalid marker: %s' % marker)
         msg = self.xmpp.make_message(mto=mto, mfrom=mfrom)
         if thread:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/slixmpp-slix-1.8.2/slixmpp/plugins/xep_0356/stanza.py 
new/slixmpp-slix-1.8.3/slixmpp/plugins/xep_0356/stanza.py
--- old/slixmpp-slix-1.8.2/slixmpp/plugins/xep_0356/stanza.py   2022-04-06 
22:44:40.000000000 +0200
+++ new/slixmpp-slix-1.8.3/slixmpp/plugins/xep_0356/stanza.py   2022-11-12 
21:39:50.000000000 +0100
@@ -7,7 +7,7 @@
 
 
 class Privilege(ElementBase):
-    namespace = "urn:xmpp:privilege:1"
+    namespace = "urn:xmpp:privilege:2"
     name = "privilege"
     plugin_attrib = "privilege"
 
@@ -24,7 +24,10 @@
 
     def presence(self):
         return self.permission("presence")
-    
+
+    def iq(self):
+        return self.permission("iq")
+
     def add_perm(self, access, type):
         # This should only be needed for servers, so maybe out of scope for 
slixmpp
         perm = Perm()
@@ -34,7 +37,7 @@
 
 
 class Perm(ElementBase):
-    namespace = "urn:xmpp:privilege:1"
+    namespace = "urn:xmpp:privilege:2"
     name = "perm"
     plugin_attrib = "perm"
     plugin_multi_attrib = "perms"
@@ -44,4 +47,4 @@
 def register():
     register_stanza_plugin(Message, Privilege)
     register_stanza_plugin(Privilege, Forwarded)
-    register_stanza_plugin(Privilege, Perm, iterable=True)
\ No newline at end of file
+    register_stanza_plugin(Privilege, Perm, iterable=True)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/slixmpp-slix-1.8.2/slixmpp/plugins/xep_0363/http_upload.py 
new/slixmpp-slix-1.8.3/slixmpp/plugins/xep_0363/http_upload.py
--- old/slixmpp-slix-1.8.2/slixmpp/plugins/xep_0363/http_upload.py      
2022-04-06 22:44:40.000000000 +0200
+++ new/slixmpp-slix-1.8.3/slixmpp/plugins/xep_0363/http_upload.py      
2022-11-12 21:39:50.000000000 +0100
@@ -101,12 +101,17 @@
 
         :param domain: Domain to disco to find a service.
         """
+        if domain is None and self.xmpp.is_component:
+            domain = self.xmpp.server_host
+
         results = await self.xmpp['xep_0030'].get_info_from_domain(
             domain=domain, **iqkwargs
         )
 
         candidates = []
         for info in results:
+            if not info['disco_info']:
+                continue
             for identity in info['disco_info']['identities']:
                 if identity[0] == 'store' and identity[1] == 'file':
                     candidates.append(info)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/slixmpp-slix-1.8.2/slixmpp/plugins/xep_0444/stanza.py 
new/slixmpp-slix-1.8.3/slixmpp/plugins/xep_0444/stanza.py
--- old/slixmpp-slix-1.8.2/slixmpp/plugins/xep_0444/stanza.py   2022-04-06 
22:44:40.000000000 +0200
+++ new/slixmpp-slix-1.8.3/slixmpp/plugins/xep_0444/stanza.py   2022-11-12 
21:39:50.000000000 +0100
@@ -6,9 +6,7 @@
 from typing import Set, Iterable
 from slixmpp.xmlstream import ElementBase
 try:
-    from emoji import UNICODE_EMOJI
-    if UNICODE_EMOJI.get('en'):
-        UNICODE_EMOJI = UNICODE_EMOJI['en']
+    from emoji import EMOJI_DATA as UNICODE_EMOJI
 except ImportError:
     UNICODE_EMOJI = None
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/slixmpp-slix-1.8.2/slixmpp/plugins/xep_0461/__init__.py 
new/slixmpp-slix-1.8.3/slixmpp/plugins/xep_0461/__init__.py
--- old/slixmpp-slix-1.8.2/slixmpp/plugins/xep_0461/__init__.py 1970-01-01 
01:00:00.000000000 +0100
+++ new/slixmpp-slix-1.8.3/slixmpp/plugins/xep_0461/__init__.py 2022-11-12 
21:39:50.000000000 +0100
@@ -0,0 +1,6 @@
+from slixmpp.plugins.base import register_plugin
+
+from .reply import XEP_0461
+from . import stanza
+
+register_plugin(XEP_0461)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/slixmpp-slix-1.8.2/slixmpp/plugins/xep_0461/reply.py 
new/slixmpp-slix-1.8.3/slixmpp/plugins/xep_0461/reply.py
--- old/slixmpp-slix-1.8.2/slixmpp/plugins/xep_0461/reply.py    1970-01-01 
01:00:00.000000000 +0100
+++ new/slixmpp-slix-1.8.3/slixmpp/plugins/xep_0461/reply.py    2022-11-12 
21:39:50.000000000 +0100
@@ -0,0 +1,48 @@
+from slixmpp.plugins import BasePlugin
+from slixmpp.types import JidStr
+from slixmpp.xmlstream import StanzaBase
+from slixmpp.xmlstream.handler import Callback
+from slixmpp.xmlstream.matcher import StanzaPath
+
+from . import stanza
+
+
+class XEP_0461(BasePlugin):
+    """XEP-0461: Message Replies"""
+
+    name = "xep_0461"
+    description = "XEP-0461: Message Replies"
+
+    dependencies = {"xep_0030"}
+    stanza = stanza
+    namespace = stanza.NS
+
+    def plugin_init(self) -> None:
+        stanza.register_plugins()
+        self.xmpp.register_handler(
+            Callback(
+                "Message replied to",
+                StanzaPath("message/reply"),
+                self._handle_reply_to_message,
+            )
+        )
+
+    def plugin_end(self):
+        self.xmpp.plugin["xep_0030"].del_feature(feature=stanza.NS)
+
+    def session_bind(self, jid):
+        self.xmpp.plugin["xep_0030"].add_feature(feature=stanza.NS)
+
+    def _handle_reply_to_message(self, msg: StanzaBase):
+        self.xmpp.event("message_reply", msg)
+
+    def send_reply(self, reply_to: JidStr, reply_id: str, **msg_kwargs):
+        """
+
+        :param reply_to: Full JID of the quoted author
+        :param reply_id: ID of the message to reply to
+        """
+        msg = self.xmpp.make_message(**msg_kwargs)
+        msg["reply"]["to"] = reply_to
+        msg["reply"]["id"] = reply_id
+        msg.send()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/slixmpp-slix-1.8.2/slixmpp/plugins/xep_0461/stanza.py 
new/slixmpp-slix-1.8.3/slixmpp/plugins/xep_0461/stanza.py
--- old/slixmpp-slix-1.8.2/slixmpp/plugins/xep_0461/stanza.py   1970-01-01 
01:00:00.000000000 +0100
+++ new/slixmpp-slix-1.8.3/slixmpp/plugins/xep_0461/stanza.py   2022-11-12 
21:39:50.000000000 +0100
@@ -0,0 +1,47 @@
+from slixmpp.stanza import Message
+from slixmpp.xmlstream import ElementBase, register_stanza_plugin
+
+NS = "urn:xmpp:reply:0"
+
+
+class Reply(ElementBase):
+    namespace = NS
+    name = "reply"
+    plugin_attrib = "reply"
+    interfaces = {"id", "to"}
+
+
+class FeatureFallBack(ElementBase):
+    # should also be a multi attrib
+    namespace = "urn:xmpp:feature-fallback:0"
+    name = "fallback"
+    plugin_attrib = "feature_fallback"
+    interfaces = {"for"}
+
+    def get_stripped_body(self):
+        # only works for a single fallback_body attrib
+        start = self["fallback_body"]["start"]
+        end = self["fallback_body"]["end"]
+        body = self.parent()["body"]
+        try:
+            start = int(start)
+            end = int(end)
+        except ValueError:
+            return body
+        else:
+            return body[:start] + body[end:]
+
+
+class FallBackBody(ElementBase):
+    # According to 
https://xmpp.org/extensions/inbox/compatibility-fallback.html
+    # this should be a multi_attrib *but* since it's a protoXEP, we'll see...
+    namespace = FeatureFallBack.namespace
+    name = "body"
+    plugin_attrib = "fallback_body"
+    interfaces = {"start", "end"}
+
+
+def register_plugins():
+    register_stanza_plugin(Message, Reply)
+    register_stanza_plugin(Message, FeatureFallBack)
+    register_stanza_plugin(FeatureFallBack, FallBackBody)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/slixmpp-slix-1.8.2/slixmpp/stanza/message.py 
new/slixmpp-slix-1.8.3/slixmpp/stanza/message.py
--- old/slixmpp-slix-1.8.2/slixmpp/stanza/message.py    2022-04-06 
22:44:40.000000000 +0200
+++ new/slixmpp-slix-1.8.3/slixmpp/stanza/message.py    2022-11-12 
21:39:50.000000000 +0100
@@ -64,9 +64,9 @@
             if self.stream:
                 use_ids = getattr(self.stream, 'use_message_ids', None)
                 if use_ids:
-                    self['id'] = self.stream.new_id()
+                    self.set_id(self.stream.new_id())
             else:
-                del self['origin_id']
+                self.del_origin_id()
 
     def get_type(self):
         """
@@ -96,8 +96,8 @@
         self.xml.attrib['id'] = value
 
         if self.stream:
-            use_orig_ids = getattr(self.stream, 'use_origin_id', None)
-            if not use_orig_ids:
+            if not getattr(self.stream, 'use_origin_id', False):
+                self.del_origin_id()
                 return None
 
         sub = self.xml.find(ORIGIN_NAME)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/slixmpp-slix-1.8.2/slixmpp/thirdparty/__init__.py 
new/slixmpp-slix-1.8.3/slixmpp/thirdparty/__init__.py
--- old/slixmpp-slix-1.8.2/slixmpp/thirdparty/__init__.py       2022-04-06 
22:44:40.000000000 +0200
+++ new/slixmpp-slix-1.8.3/slixmpp/thirdparty/__init__.py       2022-11-12 
21:39:50.000000000 +0100
@@ -3,5 +3,4 @@
 except:
     from slixmpp.thirdparty.gnupg import GPG
 
-from slixmpp.thirdparty.mini_dateutil import tzutc, tzoffset, parse_iso
 from slixmpp.thirdparty.orderedset import OrderedSet
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/slixmpp-slix-1.8.2/slixmpp/thirdparty/mini_dateutil.py 
new/slixmpp-slix-1.8.3/slixmpp/thirdparty/mini_dateutil.py
--- old/slixmpp-slix-1.8.2/slixmpp/thirdparty/mini_dateutil.py  2022-04-06 
22:44:40.000000000 +0200
+++ new/slixmpp-slix-1.8.3/slixmpp/thirdparty/mini_dateutil.py  1970-01-01 
01:00:00.000000000 +0100
@@ -1,273 +0,0 @@
-# This module is a very stripped down version of the dateutil
-# package for when dateutil has not been installed. As a replacement
-# for dateutil.parser.parse, the parsing methods from
-# 
http://blog.mfabrik.com/2008/06/30/relativity-of-time-shortcomings-in-python-datetime-and-workaround/
-
-#As such, the following copyrights and licenses applies:
-
-
-# dateutil - Extensions to the standard python 2.3+ datetime module.
-#
-# Copyright (c) 2003-2011 - Gustavo Niemeyer <gust...@niemeyer.net>
-#
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-#
-#     * Redistributions of source code must retain the above copyright notice,
-#       this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above copyright 
notice,
-#       this list of conditions and the following disclaimer in the 
documentation
-#       and/or other materials provided with the distribution.
-#     * Neither the name of the copyright holder nor the names of its
-#       contributors may be used to endorse or promote products derived from
-#       this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-# fixed_dateime
-#
-# Copyright (c) 2008, Red Innovation Ltd., Finland
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-#     * Redistributions of source code must retain the above copyright
-#       notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above copyright
-#       notice, this list of conditions and the following disclaimer in the
-#       documentation and/or other materials provided with the distribution.
-#     * Neither the name of Red Innovation nor the names of its contributors
-#       may be used to endorse or promote products derived from this software
-#       without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY RED INNOVATION ``AS IS'' AND ANY
-# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL RED INNOVATION BE LIABLE FOR ANY
-# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-
-import re
-import math
-import datetime
-
-
-ZERO = datetime.timedelta(0)
-
-
-try:
-    from dateutil.parser import parse as parse_iso
-    from dateutil.tz import tzoffset, tzutc
-except:
-    # As a stopgap, define the two timezones here based
-    # on the dateutil code.
-
-    class tzutc(datetime.tzinfo):
-
-        def utcoffset(self, dt):
-            return ZERO
-
-        def dst(self, dt):
-            return ZERO
-
-        def tzname(self, dt):
-            return "UTC"
-
-        def __eq__(self, other):
-            return (isinstance(other, tzutc) or
-                    (isinstance(other, tzoffset) and other._offset == ZERO))
-
-        def __ne__(self, other):
-            return not self.__eq__(other)
-
-        def __repr__(self):
-            return "%s()" % self.__class__.__name__
-
-        __reduce__ = object.__reduce__
-
-    class tzoffset(datetime.tzinfo):
-
-        def __init__(self, name, offset):
-            self._name = name
-            self._offset = datetime.timedelta(minutes=offset)
-
-        def utcoffset(self, dt):
-            return self._offset
-
-        def dst(self, dt):
-            return ZERO
-
-        def tzname(self, dt):
-            return self._name
-
-        def __eq__(self, other):
-            return (isinstance(other, tzoffset) and
-                    self._offset == other._offset)
-
-        def __ne__(self, other):
-            return not self.__eq__(other)
-
-        def __repr__(self):
-            return "%s(%s, %s)" % (self.__class__.__name__,
-                                   repr(self._name),
-                                   
self._offset.days*86400+self._offset.seconds)
-
-        __reduce__ = object.__reduce__
-
-
-    _fixed_offset_tzs = { }
-    UTC = tzutc()
-
-    def _get_fixed_offset_tz(offsetmins):
-        """For internal use only: Returns a tzinfo with
-        the given fixed offset. This creates only one instance
-        for each offset; the zones are kept in a dictionary"""
-
-        if offsetmins == 0:
-            return UTC
-
-        if not offsetmins in _fixed_offset_tzs:
-            if offsetmins < 0:
-                sign = '-'
-                absoff = -offsetmins
-            else:
-                sign = '+'
-                absoff = offsetmins
-
-            name = "UTC%s%02d:%02d" % (sign, int(absoff / 60), absoff % 60)
-            inst = tzoffset(name,offsetmins)
-            _fixed_offset_tzs[offsetmins] = inst
-
-        return _fixed_offset_tzs[offsetmins]
-
-
-    _iso8601_parser = re.compile(r"""
-        ^
-        (?P<year> [0-9]{4})?(?P<ymdsep>-?)?
-        (?P<month>[0-9]{2})?(?P=ymdsep)?
-        (?P<day>  [0-9]{2})?
-
-        (?P<time>
-            (?: # time part... optional... at least hour must be specified
-            (?:T|\s+)?
-                (?P<hour>[0-9]{2})
-                (?:
-                    # minutes, separated with :, or none, from hours
-                    (?P<hmssep>[:]?)
-                    (?P<minute>[0-9]{2})
-                    (?:
-                        # same for seconds, separated with :, or none, from 
hours
-                        (?P=hmssep)
-                        (?P<second>[0-9]{2})
-                    )?
-                )?
-
-                # fractions
-                (?: [,.] (?P<frac>[0-9]{1,10}))?
-
-                # timezone, Z, +-hh or +-hh:?mm. MUST BE, but complain if not 
there.
-                (
-                    (?P<tzempty>Z)
-                |
-                    (?P<tzh>[+-][0-9]{2})
-                    (?: :? # optional separator
-                        (?P<tzm>[0-9]{2})
-                    )?
-                )?
-            )
-        )?
-        $
-    """, re.X) # """
-
-    def parse_iso(timestamp):
-        """Internal function for parsing a timestamp in
-        ISO 8601 format"""
-
-        timestamp = timestamp.strip()
-
-        m = _iso8601_parser.match(timestamp)
-        if not m:
-            raise ValueError("Not a proper ISO 8601 timestamp!: %s" % 
timestamp)
-
-        vals = m.groupdict()
-        def_vals = {'year': 1970, 'month': 1, 'day': 1}
-        for key in vals:
-            if vals[key] is None:
-                vals[key] = def_vals.get(key, 0)
-            elif key not in ['time', 'ymdsep', 'hmssep', 'tzempty']:
-                vals[key] = int(vals[key])
-
-        year  = vals['year']
-        month = vals['month']
-        day   = vals['day']
-
-        if m.group('time') is None:
-            return datetime.date(year, month, day)
-
-        h, min, s, us = None, None, None, 0
-        frac = 0
-        if m.group('tzempty') == None and m.group('tzh') == None:
-            raise ValueError("Not a proper ISO 8601 timestamp: " +
-                    "missing timezone (Z or +hh[:mm])!")
-
-        if m.group('frac'):
-            frac = m.group('frac')
-            power = len(frac)
-            frac  = int(frac) / 10.0 ** power
-
-        if m.group('hour'):
-            h = vals['hour']
-
-        if m.group('minute'):
-            min = vals['minute']
-
-        if m.group('second'):
-            s = vals['second']
-
-        if frac != None:
-            # ok, fractions of hour?
-            if min == None:
-                frac, min = math.modf(frac * 60.0)
-                min = int(min)
-
-            # fractions of second?
-            if s == None:
-                frac, s = math.modf(frac * 60.0)
-                s = int(s)
-
-            # and extract microseconds...
-            us = int(frac * 1000000)
-
-        if m.group('tzempty') == 'Z':
-            offsetmins = 0
-        else:
-            # timezone: hour diff with sign
-            offsetmins = vals['tzh'] * 60
-            tzm = m.group('tzm')
-
-            # add optional minutes
-            if tzm != None:
-                tzm = int(tzm)
-                offsetmins += tzm if offsetmins > 0 else -tzm
-
-        tz = _get_fixed_offset_tz(offsetmins)
-        return datetime.datetime(year, month, day, h, min, s, us, tz)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/slixmpp-slix-1.8.2/slixmpp/version.py 
new/slixmpp-slix-1.8.3/slixmpp/version.py
--- old/slixmpp-slix-1.8.2/slixmpp/version.py   2022-04-06 22:44:40.000000000 
+0200
+++ new/slixmpp-slix-1.8.3/slixmpp/version.py   2022-11-12 21:39:50.000000000 
+0100
@@ -5,5 +5,5 @@
 # We don't want to have to import the entire library
 # just to get the version info for setup.py
 
-__version__ = '1.8.2'
-__version_info__ = (1, 8, 2)
+__version__ = '1.8.3'
+__version_info__ = (1, 8, 3)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/slixmpp-slix-1.8.2/slixmpp/xmlstream/resolver.py 
new/slixmpp-slix-1.8.3/slixmpp/xmlstream/resolver.py
--- old/slixmpp-slix-1.8.2/slixmpp/xmlstream/resolver.py        2022-04-06 
22:44:40.000000000 +0200
+++ new/slixmpp-slix-1.8.3/slixmpp/xmlstream/resolver.py        2022-11-12 
21:39:50.000000000 +0100
@@ -15,7 +15,13 @@
 log = logging.getLogger(__name__)
 
 
-class AnswerProtocol(Protocol):
+class GetHostByNameAnswerProtocol(Protocol):
+    name: str
+    aliases: List[str]
+    addresses: List[str]
+
+
+class QueryAnswerProtocol(Protocol):
     host: str
     priority: int
     weight: int
@@ -23,6 +29,9 @@
 
 
 class ResolverProtocol(Protocol):
+    def gethostbyname(self, host: str, socket_family: socket.AddressFamily) -> 
Future:
+        ...
+
     def query(self, query: str, querytype: str) -> Future:
         ...
 
@@ -147,11 +156,6 @@
 
     results = []
     for host, port in hosts:
-        if host == 'localhost':
-            if use_ipv6:
-                results.append((host, '::1', port))
-            results.append((host, '127.0.0.1', port))
-
         if use_ipv6:
             aaaa = await get_AAAA(host, resolver=resolver,
                                        use_aiodns=use_aiodns, loop=loop)
@@ -201,13 +205,13 @@
             return []
 
     # Using aiodns:
-    future = resolver.query(host, 'A')
+    future = resolver.gethostbyname(host, socket.AF_INET)
     try:
-        recs = cast(Iterable[AnswerProtocol], await future)
+        recs = cast(GetHostByNameAnswerProtocol, await future)
     except Exception as e:
         log.debug('DNS: Exception while querying for %s A records: %s', host, 
e)
-        recs = []
-    return [rec.host for rec in recs]
+        return []
+    return [addr for addr in recs.addresses]
 
 
 async def get_AAAA(host: str, *, loop: AbstractEventLoop,
@@ -249,13 +253,13 @@
             return []
 
     # Using aiodns:
-    future = resolver.query(host, 'AAAA')
+    future = resolver.gethostbyname(host, socket.AF_INET6)
     try:
-        recs = cast(Iterable[AnswerProtocol], await future)
+        recs = cast(GetHostByNameAnswerProtocol, await future)
     except Exception as e:
         log.debug('DNS: Exception while querying for %s AAAA records: %s', 
host, e)
-        recs = []
-    return [rec.host for rec in recs]
+        return []
+    return [addr for addr in recs.addresses]
 
 
 async def get_SRV(host: str, port: int, service: str,
@@ -295,12 +299,12 @@
     try:
         future = resolver.query('_%s._%s.%s' % (service, proto, host),
                                 'SRV')
-        recs = cast(Iterable[AnswerProtocol], await future)
+        recs = cast(Iterable[QueryAnswerProtocol], await future)
     except Exception as e:
         log.debug('DNS: Exception while querying for %s SRV records: %s', 
host, e)
         return []
 
-    answers: Dict[int, List[AnswerProtocol]] = {}
+    answers: Dict[int, List[QueryAnswerProtocol]] = {}
     for rec in recs:
         if rec.priority not in answers:
             answers[rec.priority] = []
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/slixmpp-slix-1.8.2/slixmpp/xmlstream/xmlstream.py 
new/slixmpp-slix-1.8.3/slixmpp/xmlstream/xmlstream.py
--- old/slixmpp-slix-1.8.2/slixmpp/xmlstream/xmlstream.py       2022-04-06 
22:44:40.000000000 +0200
+++ new/slixmpp-slix-1.8.3/slixmpp/xmlstream/xmlstream.py       2022-11-12 
21:39:50.000000000 +0100
@@ -299,8 +299,8 @@
         self.scheduled_events = {}
 
         self.ssl_context = ssl.create_default_context()
-        self.ssl_context.check_hostname = False
-        self.ssl_context.verify_mode = ssl.CERT_NONE
+        self.ssl_context.check_hostname = True
+        self.ssl_context.verify_mode = ssl.CERT_REQUIRED
 
         self.event_when_connected = "connected"
 
@@ -484,25 +484,21 @@
         if self._current_connection_attempt is None:
             return
         try:
+            server_hostname = self.default_domain if self.use_ssl else None
             await self.loop.create_connection(lambda: self,
                                                    self.address[0],
                                                    self.address[1],
                                                    ssl=ssl_context,
-                                                   
server_hostname=self.default_domain if self.use_ssl else None)
+                                                   
server_hostname=server_hostname)
             self._connect_loop_wait = 0
         except Socket.gaierror as e:
             self.event('connection_failed',
                        'No DNS record available for %s' % self.default_domain)
+            self.reschedule_connection_attempt()
         except OSError as e:
             log.debug('Connection failed: %s', e)
             self.event("connection_failed", e)
-            if self._current_connection_attempt is None:
-                return
-            self._connect_loop_wait = self._connect_loop_wait * 2 + 1
-            self._current_connection_attempt = asyncio.ensure_future(
-                self._connect_routine(),
-                loop=self.loop,
-            )
+            self.reschedule_connection_attempt()
 
     def process(self, *, forever: bool = True, timeout: Optional[int] = None) 
-> None:
         """Process all the available XMPP events (receiving or sending data on 
the
@@ -579,7 +575,7 @@
                                                        stream=self,
                                                        top_level=True,
                                                        open_only=True))
-                        self.start_stream_handler(self.xml_root)
+                        self.start_stream_handler(self.xml_root)  # type:ignore
                     self.xml_depth += 1
                 if event == 'end':
                     self.xml_depth -= 1
@@ -638,6 +634,20 @@
         self._set_disconnected_future()
         self.event("disconnected", self.disconnect_reason or exception)
 
+    def reschedule_connection_attempt(self) -> None:
+        """
+        Increase the exponential back-off and initate another background
+        _connect_routine call to connect to the server.
+        """
+        # abort if there is no ongoing connection attempt
+        if self._current_connection_attempt is None:
+            return
+        self._connect_loop_wait = min(300, self._connect_loop_wait * 2 + 1)
+        self._current_connection_attempt = asyncio.ensure_future(
+            self._connect_routine(),
+            loop=self.loop,
+        )
+
     def cancel_connection_attempt(self) -> None:
         """
         Immediately cancel the current create_connection() Future.
@@ -800,6 +810,8 @@
 
             self.ssl_context.verify_mode = ssl.CERT_REQUIRED
             self.ssl_context.load_verify_locations(cafile=ca_cert)
+        else:
+            self.ssl_context.set_default_verify_paths()
 
         return self.ssl_context
 
@@ -816,15 +828,15 @@
         try:
             if hasattr(self.loop, 'start_tls'):
                 transp = await self.loop.start_tls(self.transport,
-                                                   self, ssl_context)
+                                                   self, ssl_context,
+                                                   
server_hostname=self.default_domain)
             # Python < 3.7
             else:
                 transp, _ = await self.loop.create_connection(
                     lambda: self,
                     ssl=self.ssl_context,
                     sock=self.socket,
-                    server_hostname=self.default_domain
-                )
+                    server_hostname=self.default_domain)
         except ssl.SSLError as e:
             log.debug('SSL: Unable to connect', exc_info=True)
             log.error('CERT: Invalid certificate trust chain.')
@@ -1256,7 +1268,7 @@
                             already_run_filters.add(filter)
                             if iscoroutinefunction(filter):
                                 filter = cast(AsyncFilter, filter)
-                                task = asyncio.create_task(filter(data))
+                                task = asyncio.create_task(filter(data))  # 
type:ignore
                                 completed, pending = await wait(
                                     {task},
                                     timeout=1,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/slixmpp-slix-1.8.2/tests/test_stanza_xep_0055.py 
new/slixmpp-slix-1.8.3/tests/test_stanza_xep_0055.py
--- old/slixmpp-slix-1.8.2/tests/test_stanza_xep_0055.py        1970-01-01 
01:00:00.000000000 +0100
+++ new/slixmpp-slix-1.8.3/tests/test_stanza_xep_0055.py        2022-11-12 
21:39:50.000000000 +0100
@@ -0,0 +1,59 @@
+import unittest
+
+from slixmpp import register_stanza_plugin, Iq
+from slixmpp.test import SlixTest
+
+from slixmpp.plugins.xep_0055 import stanza
+
+
+class TestJabberSearch(SlixTest):
+    def setUp(self):
+        register_stanza_plugin(Iq, stanza.Search)
+        self.stream_start(plugins={"xep_0055"})
+
+    def testRequestSearchFields(self):
+        iq = self.Iq()
+        iq.set_from("jul...@capulet.com/balcony")
+        iq.set_to("characters.shakespeare.lit")
+        iq.set_type("get")
+        iq.enable("search")
+        iq["id"] = "0"
+        self.check(
+            iq,
+            """
+            <iq type='get'
+                from='jul...@capulet.com/balcony'
+                to='characters.shakespeare.lit'>
+              <query xmlns='jabber:iq:search'/>
+            </iq>
+            """,
+        )
+
+    def testSendSearch(self):
+        iq = self.xmpp["xep_0055"].make_search_iq(
+            ifrom="jul...@capulet.com/balcony", 
ito="characters.shakespeare.lit"
+        )
+        iq["search"]["form"].add_field(var="x-gender", value="male")
+        self.check(
+            iq,
+            """
+            <iq type='set'
+                from='jul...@capulet.com/balcony'
+                to='characters.shakespeare.lit'>
+              <query xmlns='jabber:iq:search'>
+                <x xmlns='jabber:x:data' type='submit'>
+                  <field type='hidden' var='FORM_TYPE'>
+                    <value>jabber:iq:search</value>
+                  </field>
+                  <field var='x-gender'>
+                    <value>male</value>
+                  </field>
+                </x>
+              </query>
+            </iq>
+            """,
+            use_values=False,
+        )
+
+
+suite = unittest.TestLoader().loadTestsFromTestCase(TestJabberSearch)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/slixmpp-slix-1.8.2/tests/test_stanza_xep_0356.py 
new/slixmpp-slix-1.8.3/tests/test_stanza_xep_0356.py
--- old/slixmpp-slix-1.8.2/tests/test_stanza_xep_0356.py        2022-04-06 
22:44:40.000000000 +0200
+++ new/slixmpp-slix-1.8.3/tests/test_stanza_xep_0356.py        2022-11-12 
21:39:50.000000000 +0100
@@ -13,7 +13,7 @@
     def testAdvertisePermission(self):
         xmlstring = """
             <message from='capulet.net' to='pubub.capulet.lit'>
-                <privilege xmlns='urn:xmpp:privilege:1'>
+                <privilege xmlns='urn:xmpp:privilege:2'>
                     <perm access='roster' type='both'/>
                     <perm access='message' type='outgoing'/>
                     <perm access='presence' type='managed_entity'/>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/slixmpp-slix-1.8.2/tests/test_stanza_xep_0461.py 
new/slixmpp-slix-1.8.3/tests/test_stanza_xep_0461.py
--- old/slixmpp-slix-1.8.2/tests/test_stanza_xep_0461.py        1970-01-01 
01:00:00.000000000 +0100
+++ new/slixmpp-slix-1.8.3/tests/test_stanza_xep_0461.py        2022-11-12 
21:39:50.000000000 +0100
@@ -0,0 +1,48 @@
+import unittest
+from slixmpp import Message
+from slixmpp.test import SlixTest
+from slixmpp.plugins.xep_0461 import stanza
+
+
+class TestReply(SlixTest):
+    def setUp(self):
+        stanza.register_plugins()
+
+    def testReply(self):
+        message = Message()
+        message["reply"]["id"] = "some-id"
+        message["body"] = "some-body"
+
+        self.check(
+            message,
+            """
+            <message>
+              <reply xmlns="urn:xmpp:reply:0" id="some-id" />
+              <body>some-body</body>
+            </message>
+            """,
+        )
+
+    def testFallback(self):
+        message = Message()
+        message["body"] = "12345\nrealbody"
+        message["feature_fallback"]["for"] = "NS"
+        message["feature_fallback"]["fallback_body"]["start"] = "0"
+        message["feature_fallback"]["fallback_body"]["end"] = "6"
+
+        self.check(
+            message,
+            """
+            <message xmlns="jabber:client">
+              <body>12345\nrealbody</body>
+              <fallback xmlns='urn:xmpp:feature-fallback:0' for='NS'>
+                <body start="0" end="6" />
+              </fallback>
+            </message>
+            """,
+        )
+
+        assert message["feature_fallback"].get_stripped_body() == "realbody"
+
+
+suite = unittest.TestLoader().loadTestsFromTestCase(TestReply)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/slixmpp-slix-1.8.2/tests/test_stream_xep_0055.py 
new/slixmpp-slix-1.8.3/tests/test_stream_xep_0055.py
--- old/slixmpp-slix-1.8.2/tests/test_stream_xep_0055.py        1970-01-01 
01:00:00.000000000 +0100
+++ new/slixmpp-slix-1.8.3/tests/test_stream_xep_0055.py        2022-11-12 
21:39:50.000000000 +0100
@@ -0,0 +1,170 @@
+import unittest
+from slixmpp.test import SlixTest
+
+
+class TestJabberSearch(SlixTest):
+    def setUp(self):
+        self.stream_start(
+            mode="component",
+            plugin_config={
+                "xep_0055": {
+                    "form_fields": {"first", "last"},
+                    "form_instructions": "INSTRUCTIONS",
+                    "form_title": "User Directory Search",
+                }
+            },
+            jid="characters.shakespeare.lit",
+            plugins={"xep_0055"}
+        )
+        self.xmpp["xep_0055"].api.register(get_results, "search_query")
+        self.xmpp["xep_0055"].api.register(get_results, "search_query")
+
+    def tearDown(self):
+        self.stream_close()
+
+    def testRequestingSearchFields(self):
+        self.recv(
+            """
+            <iq type='get'
+                from='jul...@capulet.com/balcony'
+                to='characters.shakespeare.lit'
+                id='search3'
+                xml:lang='en'>
+              <query xmlns='jabber:iq:search'/>
+            </iq>
+            """
+        )
+        self.send(
+            """
+            <iq type='result'
+                from='characters.shakespeare.lit'
+                to='jul...@capulet.com/balcony'
+                id='search3'
+                xml:lang='en'>
+              <query xmlns='jabber:iq:search'>
+                <x xmlns='jabber:x:data' type='form'>
+                  <title>User Directory Search</title>
+                  <instructions>INSTRUCTIONS</instructions>
+                  <field type='hidden'
+                         var='FORM_TYPE'>
+                    <value>jabber:iq:search</value>
+                  </field>
+                  <field var='first'/>
+                  <field var='last'/>
+                </x>
+              </query>
+            </iq>
+            """,
+            use_values=False,
+        )
+
+    def testSearchResult(self):
+        self.recv(
+            """
+            <iq type='get'
+                from='jul...@capulet.com/balcony'
+                to='characters.shakespeare.lit'
+                id='search2'
+                xml:lang='en'>
+              <query xmlns='jabber:iq:search'>
+                <x xmlns='jabber:x:data' type='submit'>
+                  <field type='hidden' var='FORM_TYPE'>
+                    <value>jabber:iq:search</value>
+                  </field>
+                  <field var='last'>
+                    <value>Montague</value>
+                  </field>
+                </x>
+              </query>
+            </iq>
+            """
+        )
+        self.send(
+            """
+            <iq type='result'
+                from='characters.shakespeare.lit'
+                to='jul...@capulet.com/balcony'
+                id='search2'
+                xml:lang='en'>
+              <query xmlns='jabber:iq:search'>
+                <x xmlns='jabber:x:data' type='result'>
+                  <field type='hidden' var='FORM_TYPE'>
+                    <value>jabber:iq:search</value>
+                  </field>
+                  <reported>
+                    <field var='first' label='Given Name' />
+                    <field var='last' label='Family Name' />
+                  </reported>
+                  <item>
+                    <field var='first'><value>Benvolio</value></field>
+                    <field var='last'><value>Montague</value></field>
+                  </item>
+                </x>
+              </query>
+            </iq>
+            """,
+            use_values=False,  # TypeError: element indices must be integers 
without that
+        )
+
+    def testSearchNoResult(self):
+        self.xmpp["xep_0055"].api.register(get_results, "search_query")
+        self.recv(
+            """
+            <iq type='get'
+                from='jul...@capulet.com/balcony'
+                to='characters.shakespeare.lit'
+                id='search2'
+                xml:lang='en'>
+              <query xmlns='jabber:iq:search'>
+                <x xmlns='jabber:x:data' type='submit'>
+                  <field type='hidden' var='FORM_TYPE'>
+                    <value>jabber:iq:search</value>
+                  </field>
+                  <field var='last'>
+                    <value>Capulet</value>
+                  </field>
+                </x>
+              </query>
+            </iq>
+            """
+        )
+        self.send(
+            """
+            <iq type='result'
+                from='characters.shakespeare.lit'
+                to='jul...@capulet.com/balcony'
+                id='search2'
+                xml:lang='en'>
+              <query xmlns='jabber:iq:search'>
+                <x xmlns='jabber:x:data' type='result'>
+                  <field type='hidden' var='FORM_TYPE'>
+                    <value>jabber:iq:search</value>
+                  </field>
+                  <reported>
+                    <field var='first' label='Given Name' />
+                    <field var='last' label='Family Name' />
+                  </reported>
+                </x>
+              </query>
+            </iq>
+            """,
+            use_values=False,  # TypeError: element indices must be integers 
without that
+        )
+
+async def get_results(jid, node, ifrom, iq):
+    reply = iq.reply()
+    form = reply["search"]["form"]
+    form["type"] = "result"
+
+    form.add_reported("first", label="Given Name")
+    form.add_reported("last", label="Family Name")
+
+    d = iq["search"]["form"].get_values()
+
+    if d["last"] == "Montague":
+        form.add_item({"first": "Benvolio", "last": "Montague"})
+
+    return reply
+
+
+suite = unittest.TestLoader().loadTestsFromTestCase(TestJabberSearch)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/slixmpp-slix-1.8.2/tests/test_stream_xep_0356.py 
new/slixmpp-slix-1.8.3/tests/test_stream_xep_0356.py
--- old/slixmpp-slix-1.8.2/tests/test_stream_xep_0356.py        2022-04-06 
22:44:40.000000000 +0200
+++ new/slixmpp-slix-1.8.3/tests/test_stream_xep_0356.py        2022-11-12 
21:39:50.000000000 +0100
@@ -31,7 +31,7 @@
         self.recv(
             """
             <message from='capulet.net' to='pubub.capulet.lit' id='54321'>
-                <privilege xmlns='urn:xmpp:privilege:1'>
+                <privilege xmlns='urn:xmpp:privilege:2'>
                     <perm access='roster' type='both'/>
                     <perm access='message' type='outgoing'/>
                 </privilege>
@@ -95,7 +95,7 @@
     def testMakeOutgoingMessage(self):
         xmlstring = """
         <message xmlns="jabber:component:accept" from='pubsub.capulet.lit' 
to='capulet.net'>
-            <privilege xmlns='urn:xmpp:privilege:1'>
+            <privilege xmlns='urn:xmpp:privilege:2'>
                 <forwarded xmlns='urn:xmpp:forward:0'>
                     <message from="jul...@capulet.lit" to="ro...@montague.lit" 
xmlns="jabber:client">
                         <body>I do not hate you</body>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/slixmpp-slix-1.8.2/tests/test_stream_xep_0461.py 
new/slixmpp-slix-1.8.3/tests/test_stream_xep_0461.py
--- old/slixmpp-slix-1.8.2/tests/test_stream_xep_0461.py        1970-01-01 
01:00:00.000000000 +0100
+++ new/slixmpp-slix-1.8.3/tests/test_stream_xep_0461.py        2022-11-12 
21:39:50.000000000 +0100
@@ -0,0 +1,48 @@
+import logging
+import unittest
+from slixmpp.test import SlixTest
+
+
+class TestReply(SlixTest):
+    def setUp(self):
+        self.stream_start(plugins=["xep_0461"])
+
+    def tearDown(self):
+        self.stream_close()
+
+    def testFallBackBody(self):
+        async def on_reply(msg):
+            start = msg["feature_fallback"]["fallback_body"]["start"]
+            end = msg["feature_fallback"]["fallback_body"]["end"]
+            self.xmpp["xep_0461"].send_reply(
+                reply_to=msg.get_from(),
+                reply_id=msg.get_id(),
+                mto="t...@test.com",
+                mbody=f"{start} to {end}",
+            )
+
+        self.xmpp.add_event_handler("message_reply", on_reply)
+
+        self.recv(
+            """
+            <message id="other-id" from="f...@from.com/res">
+              <reply xmlns="urn:xmpp:reply:0" id="some-id" />
+              <body>&gt; quoted\nsome-body</body>
+                <fallback xmlns='urn:xmpp:feature-fallback:0' 
for='urn:xmpp:reply:0'>
+                   <body start="0" end="8" />
+                </fallback>
+            </message>
+            """
+        )
+        self.send(
+            """
+            <message xmlns="jabber:client" to="t...@test.com" type="normal">
+              <reply xmlns="urn:xmpp:reply:0" id="other-id" 
to="f...@from.com/res" />
+              <body>0 to 8</body>
+            </message>
+            """
+        )
+
+
+logging.basicConfig(level=logging.DEBUG)
+suite = unittest.TestLoader().loadTestsFromTestCase(TestReply)

Reply via email to