Skip to content

Commit

Permalink
#3978 Cythonized version uses stricter type checks
Browse files Browse the repository at this point in the history
  • Loading branch information
totaam committed Sep 29, 2023
1 parent 9c8ba82 commit e0c462d
Show file tree
Hide file tree
Showing 14 changed files with 93 additions and 64 deletions.
2 changes: 1 addition & 1 deletion tests/unittests/unit/client/mixins/logging_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def test_logging(self):
})
assert len(self.packets)==0
logger = Logger("util")
message = b"hello"
message = "hello"
logger.info(message)
assert len(self.packets)==1
packet = self.packets[0]
Expand Down
27 changes: 21 additions & 6 deletions tests/unittests/unit/net/digest_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,14 @@ class TestDigest(unittest.TestCase):

def test_invalid_digest(self):
for invalid_digest in (None, "foo", "hmac", "hmac+INVALID_HASH_ALGO"):
assert get_digest_module(invalid_digest) is None
assert not gendigest(invalid_digest, "bar", "0"*16)
try:
assert get_digest_module(invalid_digest) is None
except TypeError:
pass
try:
assert not gendigest(invalid_digest, "bar", "0"*16)
except TypeError:
pass

def test_all_digests(self):
for digest in get_digests():
Expand All @@ -31,10 +37,19 @@ def test_all_digests(self):
password = "secret"
d = gendigest(digest, password, salt)
assert d is not None
assert not verify_digest(digest, None, salt, d)
assert not verify_digest(digest, password, None, d)
assert not verify_digest(digest, password, salt, None)
assert not verify_digest(digest, password, salt, d[:-1])
def nvd(password=password, salt=salt, response=d):
try:
r = verify_digest(digest, password, salt, response)
assert not r
except TypeError:
pass
nvd(password=None)
nvd(salt=None)
nvd(response=None)
#truncated:
nvd(password=password[1:])
nvd(salt=salt[1:])
nvd(response=d[1:])
assert verify_digest(digest, password, salt, d)

def test_choose_digest(self):
Expand Down
3 changes: 2 additions & 1 deletion tests/unittests/unit/net/packet_encoding_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ def test_env_log(self):
print("error calling decode(%s, %s) for encoder %s" % (v, flag, x))
raise
#one-shot function:
assert packet_encoding.pack_one_packet(["hello", {}])
packet = ("hello", {})
assert packet_encoding.pack_one_packet(packet)

def main():
unittest.main()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def f(v, key=b""):
"sec-websocket-protocol" : "binary",
"sec-websocket-accept" : "key",
})
key = b"somekey"
key = "somekey"
verify_response_headers({
"upgrade" : "websocket",
"sec-websocket-protocol" : "binary",
Expand Down
5 changes: 4 additions & 1 deletion tests/unittests/unit/notifications/common_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ def test_parse_image_path(self):
f.close()
for x in ("", None, "/invalid-path", f.name):
with silence_error(common):
assert common.parse_image_path(x) is None
try:
assert common.parse_image_path(x) is None
except TypeError:
pass
finally:
os.unlink(f.name)

Expand Down
2 changes: 1 addition & 1 deletion tests/unittests/unit/scripts/main_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def test_find_mode_pos(self):
for v in (0, "a", ""):
try:
find_mode_pos(args, v)
except InitException:
except (InitException, TypeError):
pass
else:
raise RuntimeError(f"find_mode_pos should have failed for {args} and {v}")
Expand Down
10 changes: 4 additions & 6 deletions tests/unittests/unit/x11/size_hints_util_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ class TestX11Keyboard(unittest.TestCase):
def test_sanitize(self):
from xpra.x11.models import size_hints_util
MAX_ASPECT = size_hints_util.MAX_ASPECT
sanitize_size_hints = size_hints_util.sanitize_size_hints
with silence_warn(size_hints_util):
INTPAIRS = (0, "foo", (1,))
for attr, values in {
Expand All @@ -29,23 +28,22 @@ def test_sanitize(self):
"increment" : INTPAIRS,
}.items():
for value in values:
hints = {}
hints[attr] = value
sanitize_size_hints(hints)
hints = { attr : value }
size_hints_util.sanitize_size_hints(hints)
assert attr not in hints, "%s=%s should have been removed" % (attr, value)
hints = {
"minimum-size" : (-1, -1),
"maximum-size" : (-1, -1),
}
sanitize_size_hints(hints)
size_hints_util.sanitize_size_hints(hints)
assert hints.get("minimum-size") is None
assert hints.get("maximum-size") is None
for mins, maxs in ((100, 50), (512, 128), (512, 256),):
hints = {
"minimum-size" : (mins, mins),
"maximum-size" : (maxs, maxs),
}
sanitize_size_hints(hints)
size_hints_util.sanitize_size_hints(hints)
assert hints.get("minimum-size")==hints.get("maximum-size")

def main():
Expand Down
5 changes: 3 additions & 2 deletions xpra/client/gui/tray_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from time import monotonic
from collections import deque

from xpra.common import noop
from xpra.platform.paths import get_icon_filename
from xpra.log import Logger

Expand All @@ -20,8 +21,8 @@ class TrayBase:
Utility superclass for all tray implementations
"""

def __init__(self, _client, app_id, menu, tooltip:str, icon_filename:str,
size_changed_cb:Callable, click_cb:Callable, mouseover_cb:Callable, exit_cb:Callable):
def __init__(self, _client, app_id, menu, tooltip:str="", icon_filename:str="",
size_changed_cb:Callable=noop, click_cb:Callable=noop, mouseover_cb:Callable=noop, exit_cb:Callable=noop):
#we don't keep a reference to client,
#because calling functions on the client directly should be discouraged
self.app_id = app_id
Expand Down
4 changes: 2 additions & 2 deletions xpra/platform/darwin/shadow_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,8 @@ def get_keyboard_config(self, _props=None) -> KeyboardConfig:

def make_tray_widget(self):
from xpra.client.gtk3.statusicon_tray import GTKStatusIconTray
return GTKStatusIconTray(self, 0, self.tray, "Xpra Shadow Server", None, None,
self.tray_click_callback, mouseover_cb=None, exit_cb=self.tray_exit_callback)
return GTKStatusIconTray(self, 0, self.tray, "Xpra Shadow Server",
click_cb=self.tray_click_callback, mouseover_cb=None, exit_cb=self.tray_exit_callback)


def setup_capture(self) -> OSXRootCapture:
Expand Down
2 changes: 1 addition & 1 deletion xpra/platform/win32/shadow_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ def print_screen_info(self) -> None:
def make_tray_widget(self):
from xpra.platform.win32.tray import Win32Tray
return Win32Tray(self, XPRA_APP_ID, self.tray_menu, "Xpra Shadow Server", "server-notconnected",
None, self.tray_click_callback, None, self.tray_exit_callback)
click_cb=self.tray_click_callback, exit_cb=self.tray_exit_callback)


def setup_capture(self):
Expand Down
4 changes: 2 additions & 2 deletions xpra/scripts/parsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -614,11 +614,11 @@ def parse_ssh_option(ssh_setting:str) -> list[str]:
from xpra.net.ssh.util import nogssapi_context
with nogssapi_context():
import paramiko
assert paramiko
assert paramiko, "paramiko not found"
ssh_cmd = ["paramiko"]
if is_debug_enabled("ssh"):
Logger("ssh").info("using paramiko ssh backend")
except ImportError:
except (ImportError, AssertionError):
log = Logger("ssh")
log(f"parse_ssh_option({ssh_setting})", exc_info=True)
from xpra.platform.features import DEFAULT_SSH_COMMAND
Expand Down
6 changes: 4 additions & 2 deletions xpra/server/shadow/gtk_shadow_server_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -424,9 +424,11 @@ def make_tray_widget(self):
for c in classes:
try:
w = c(self, XPRA_APP_ID, self.tray, "Xpra Shadow Server",
None, None, self.tray_click_callback, mouseover_cb=None, exit_cb=self.tray_exit_callback)
return w
click_cb=self.tray_click_callback, exit_cb=self.tray_exit_callback)
if w:
return w
except Exception as e:
traylog(f"{c}(..)", exc_info=True)
errs.append((c, e))
traylog.error("Error: all system tray implementations have failed")
for c, err in errs:
Expand Down
5 changes: 3 additions & 2 deletions xpra/server/shadow/shadow_server_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ def get_notification_tray(self):
def notify_startup_complete(self) -> None:
self.do_notify_startup("Xpra shadow server is ready", replaces_nid=NotificationID.STARTUP)

def do_notify_startup(self, title:str, body:str="", replaces_nid:int=0) -> None:
def do_notify_startup(self, title:str, body:str="", replaces_nid:int|NotificationID=0) -> None:
# this is overridden here so that we can show the notification
# directly on the screen we shadow
notifylog("do_notify_startup%s", (title, body, replaces_nid))
Expand Down Expand Up @@ -444,7 +444,8 @@ def send_initial_windows(self, ss, sharing:bool=False) -> None:
for wid in sorted(self._id_to_window.keys()):
window = self._id_to_window[wid]
w, h = window.get_dimensions()
ss.new_window("new-window", wid, window, 0, 0, w, h, self.client_properties.get(wid, {}).get(ss.uuid))
client_props = self.client_properties.get(wid, {}).get(ss.uuid, {})
ss.new_window("new-window", wid, window, 0, 0, w, h, client_props)


def _add_new_window(self, window) -> None:
Expand Down
80 changes: 44 additions & 36 deletions xpra/x11/models/size_hints_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,13 @@ def sanitize_size_hints(size_hints : dict[str,Any]) -> None:
for attr in ("minimum-aspect-ratio", "maximum-aspect-ratio"):
v = size_hints.get(attr)
if v is not None:
try:
f = float(v[0])/float(v[1])
except (ValueError, ZeroDivisionError):
if v[1]==0:
f = None
else:
try:
f = float(v[0])/float(v[1])
except (ValueError, ZeroDivisionError):
f = None
if f is None or f<=0 or f>=MAX_ASPECT:
log.warn("Warning: clearing invalid aspect hint value for %s: %s", attr, v)
del size_hints[attr]
Expand All @@ -54,43 +57,48 @@ def sanitize_size_hints(size_hints : dict[str,Any]) -> None:
log("clearing invalid size hint value for %s: %s", attr, v)
del size_hints[attr]
#if max-size is smaller than min-size (bogus), clamp it..
clamped = False
mins = size_hints.get("minimum-size")
maxs = size_hints.get("maximum-size")
if mins is not None and maxs is not None:
clamped = False
minw,minh = mins
maxw,maxh = maxs
if minw<0 and minh<0:
if mins:
minw, minh = mins
if minw<=0 and minh<=0:
#doesn't do anything
size_hints["minimum-size"] = None
size_hints.pop("minimum-size")
mins = None
clamped = True
if maxw<=0 or maxh<=0:
maxs = size_hints.get("maximum-size")
if maxs:
maxw,maxh = maxs
if maxw<=0 and maxh<=0:
#doesn't make sense!
size_hints["maximum-size"] = None
maxs = None
clamped = True
if mins and maxs:
minw, minh = mins
maxw, maxh = maxs
if minw>0 and minw>maxw:
#min higher than max!
if minw<=256:
maxw = minw
elif maxw>=256:
minw = maxw
else:
minw = maxw = 256
clamped = True
if minh>0 and minh>maxh:
#min higher than max!
if minh<=256:
maxh = minh
elif maxh>=256:
minh = maxh
else:
minh = maxh = 256
clamped = True
if not clamped:
if minw>0 and minw>maxw:
#min higher than max!
if minw<=256:
maxw = minw
elif maxw>=256:
minw = maxw
else:
minw = maxw = 256
clamped = True
if minh>0 and minh>maxh:
#min higher than max!
if minh<=256:
maxh = minh
elif maxh>=256:
minh = maxh
else:
minh = maxh = 256
clamped = True
if clamped:
size_hints["minimum-size"] = minw, minh
size_hints["maximum-size"] = maxw, maxh
if clamped:
log.warn("Warning: invalid size hints")
log.warn(" min_size=%s / max_size=%s", mins, maxs)
log.warn(" changed to: %s / %s", size_hints.get("minimum-size"), size_hints.get("maximum-size"))
size_hints["minimum-size"] = minw, minh
size_hints["maximum-size"] = maxw, maxh
if clamped:
log.warn("Warning: invalid size hints")
log.warn(" min_size=%s / max_size=%s", mins, maxs)
log.warn(" changed to: %s / %s", size_hints.get("minimum-size"), size_hints.get("maximum-size"))

0 comments on commit e0c462d

Please sign in to comment.