From 2e52f544f11af8c005f076434366c14f234e797c Mon Sep 17 00:00:00 2001 From: funman300 Date: Sun, 17 May 2026 21:29:38 -0700 Subject: [PATCH] fix(data): enforce 32-char display_name limit at sync client boundary (M-22) opt_in_leaderboard in sync_client.rs was passing display_name through as-is, relying solely on the engine's .chars().take(32) call upstream. Add the truncation in the sync client so any caller is protected, and also apply it at save-time in handle_display_name_confirm so settings never stores an over-length name. Co-Authored-By: Claude Sonnet 4.6 --- solitaire_data/src/sync_client.rs | 3 +++ solitaire_engine/src/leaderboard_plugin.rs | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/solitaire_data/src/sync_client.rs b/solitaire_data/src/sync_client.rs index 408ec98..71a74fd 100644 --- a/solitaire_data/src/sync_client.rs +++ b/solitaire_data/src/sync_client.rs @@ -309,6 +309,9 @@ impl SyncProvider for SolitaireServerClient { async fn opt_in_leaderboard(&self, display_name: &str) -> Result<(), SyncError> { let token = self.access_token()?; let url = format!("{}/api/leaderboard/opt-in", self.base_url); + // Enforce the server's 32-char column limit at the client boundary so + // the server never receives an over-length name regardless of caller. + let display_name: String = display_name.chars().take(32).collect(); let resp = self .client diff --git a/solitaire_engine/src/leaderboard_plugin.rs b/solitaire_engine/src/leaderboard_plugin.rs index afb70d9..370fd98 100644 --- a/solitaire_engine/src/leaderboard_plugin.rs +++ b/solitaire_engine/src/leaderboard_plugin.rs @@ -746,7 +746,7 @@ fn handle_display_name_confirm( return; } if let Some(mut settings) = settings { - let trimmed = buf.0.trim().to_string(); + let trimmed: String = buf.0.trim().chars().take(32).collect(); settings.0.leaderboard_display_name = if trimmed.is_empty() { None } else {