fix(multiplayer): validate client revisions

This commit is contained in:
Josh Creek
2026-09-01 21:59:32 +01:00
parent f491725144
commit a60c1a097e
5 changed files with 35 additions and 4 deletions
+10 -2
View File
@@ -419,9 +419,9 @@ func _handle_websocket_packet(packet: PackedByteArray) -> void:
static func _valid_websocket_event(event: Dictionary) -> bool:
if not event.has("event") or not event["event"] is String or String(event["event"]).is_empty():
return false
if not event.has("revision") or not (event["revision"] is int or event["revision"] is float):
if not event.has("revision") or not _valid_revision(event["revision"]):
return false
if int(event["revision"]) < 0 or not event.has("resource_id") or not event["resource_id"] is String or String(event["resource_id"]).is_empty():
if not event.has("resource_id") or not event["resource_id"] is String or String(event["resource_id"]).is_empty():
return false
if not event.has("occurred_at") or not event["occurred_at"] is String or String(event["occurred_at"]).is_empty():
return false
@@ -437,6 +437,14 @@ static func _valid_websocket_event(event: Dictionary) -> bool:
return false
static func _valid_revision(value: Variant) -> bool:
if value is int:
return int(value) >= 0
if value is float:
return is_finite(float(value)) and float(value) >= 0.0 and float(value) == floor(float(value))
return false
func _on_resync_required(resource_id: String) -> void:
if not _operation.is_empty():
_pending_resync_resource_id = resource_id
+10 -2
View File
@@ -49,7 +49,7 @@ func begin_queue(new_ticket_id: String, new_playlist: String) -> bool:
func apply_ticket_update(update: Dictionary) -> bool:
if not _has_string(update, "ticket_id") or not update.has("revision") or not update.has("state"):
if not _has_string(update, "ticket_id") or not update.has("revision") or not _valid_revision(update["revision"]) or not update.has("state"):
return _request_resync(self.ticket_id)
if ticket_id.is_empty() or String(update["ticket_id"]) != ticket_id:
return _request_resync(self.ticket_id)
@@ -94,7 +94,7 @@ func apply_ticket_update(update: Dictionary) -> bool:
func apply_proposal_update(update: Dictionary) -> bool:
if not _has_string(update, "proposal_id") or not update.has("revision") or not update.has("state"):
if not _has_string(update, "proposal_id") or not update.has("revision") or not _valid_revision(update["revision"]) or not update.has("state"):
return _request_resync(proposal_id)
var incoming_id := String(update["proposal_id"])
if proposal_id.is_empty():
@@ -270,3 +270,11 @@ func _is_legal_ticket_transition(from: String, to: String) -> bool:
func _has_string(value: Dictionary, key: String) -> bool:
return value.has(key) and value[key] is String and not String(value[key]).is_empty()
func _valid_revision(value: Variant) -> bool:
if value is int:
return int(value) >= 0
if value is float:
return is_finite(float(value)) and float(value) >= 0.0 and float(value) == floor(float(value))
return false