refact: update with metadata#54
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughAdds end-to-end signed update metadata publication and tooling, strict GitHub release URL validation, verified-artifact resolution and atomic installs, downloader and TLS hardening, Windows/macOS verified install flows, Flutter FFI/UI wiring for verified updates, deterministic Python tooling and tests, and locale keys. ChangesVerified Update Implementation
Estimated code review effort🎯 5 (Critical) | ⏱️ ~120 minutes Poem
✨ Finishing Touches🧪 Generate unit tests (beta)
|
There was a problem hiding this comment.
Actionable comments posted: 18
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/platform/macos.rs (1)
1040-1047:⚠️ Potential issue | 🟠 Major | 🏗️ Heavy liftRemove the legacy extracted-DMG fallback from the privileged install path.
update_from_dmg()still copies the app bundle into/tmp/...and then feeds that extracted bundle intoupdate_me_from_app_dir(). The stack context says the CLI still keeps a legacy DMG fallback, so this path remains reachable and bypasses the new read-only verified-DMG flow; a same-user process can tamper with the extracted.appbefore the privileged swap consumes it.Please either fail closed when sidecar metadata/signature are missing, or route the fallback through the mounted-DMG/verified path instead of staging a writable bundle in
/tmp.Also applies to: 1294-1340
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/platform/macos.rs` around lines 1040 - 1047, update_from_dmg currently stages an extracted writable .app in /tmp via extract_dmg and then calls update_extracted/update_me_from_app_dir, which allows tampering; instead, change update_from_dmg (and the similar block at lines ~1294-1340) to fail closed when sidecar metadata/signature are missing after extraction OR (preferred) avoid writable staging entirely by mounting the DMG and routing the update through the mounted, verified read-only path: after extract_dmg/mount_dmg, validate sidecar signature/metadata (use the existing verifier code you already have), and if valid call update_me_from_app_dir/update_extracted with the mounted read-only path (or return Err when verification fails); remove the codepath that copies the bundle into /tmp and ensure update_extracted/update_me_from_app_dir accept a mounted-path input rather than an extracted-temp path so the privileged swap always consumes a verified read-only bundle.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/flutter-build.yml:
- Around line 854-883: The macOS metadata fragment and DMG uploads run whenever
UPDATE_METADATA_SIGNING_ENABLED is true even if the built DMG isn't actually
code-signed/notarized; modify the "Generate update metadata fragment" and the
"Upload macOS DMG fragment"/"Upload signed macOS DMG" steps so they only proceed
after verifying the DMG is properly signed/notarized (e.g. run a pre-check using
codesign --verify --deep --strict or a small verification script that sets an
env like MACOS_DMG_SIGNED=true), or gate those steps on a new env var (e.g.
MACOS_DMG_SIGNED == 'true'); ensure the verification occurs before calling
python3 res/generate_update_metadata.py (which uses TAG_NAME, VERSION,
matrix.job.arch) and before uploading the fragment and DMG artifacts.
- Around line 305-331: Replace mutable GitHub Action refs with immutable SHA
pins in the update-metadata-related steps: locate uses of
actions/upload-artifact@master, actions/download-artifact@master,
actions/setup-python@v5, actions/checkout@v4, dtolnay/rust-toolchain@v1 and
softprops/action-gh-release@v1 in the flutter-build.yml (the update-metadata
publish/download steps and related jobs) and change each to the corresponding
repository commit SHA (the exact immutable commit for the version you intend to
use); ensure the softprops/action-gh-release entry matches the SHA used
elsewhere in the workflow for consistency and update any other occurrences to
the same pinned SHAs.
- Around line 894-897: The job publish-signed-update-metadata lacks an explicit
permissions block so actions like softprops/action-gh-release may run with
read-only GITHUB_TOKEN; add a job-level permissions: block for that job (e.g.,
permissions: contents: write) to ensure the GITHUB_TOKEN has the required write
scope, placing the block directly under the publish-signed-update-metadata
declaration in the workflow.
In `@flutter/lib/desktop/widgets/update_progress.dart`:
- Around line 29-31: The branch that handles downloadUrl starting with 'error:'
should reuse the same GitHub rate-limit mapping used by _onError so the
verification failure shows the friendly retry guidance; modify the block where
downloadUrl.startsWith('error:') is handled to run the error string through the
same mapping/marker check used by _onError (instead of passing the raw error)
and then call _showUpdateError(releasePageUrl, mappedError). Ensure you
reference the same marker logic used for verified-download-url-* so users see
the consistent rate-limit message during the verification step as well.
In `@res/generate_update_metadata.py`:
- Around line 134-145: In command_sign, after reading and validating each
fragment (the loop that calls read_json, validate_fragment and
artifact_identity), add checks to reject fragments whose URL or file name do not
match the current release and the fragment contents: verify the artifact['url']
references the same release id (or otherwise belongs to args.release_id) and
that the basename of the URL matches artifact['file_name'] (or the artifact_name
returned by artifact_identity); if either check fails call fail(...) with a
clear message indicating cross-release or filename mismatch so
malformed/cross-release fragments are rejected early. Ensure these checks run
before adding to seen and before sorting so sign only processes consistent
artifacts.
- Around line 117-133: The command_fragment function currently reads the entire
artifact into memory with artifact_path.read_bytes(); change it to avoid that by
using artifact_path.stat().st_size for "size" and the existing streaming helper
sha256_hex(...) to compute "sha256" without loading the full file. Keep the
existing checks (parse_artifact_url, filename match, validate_release_id) and
populate fragment with "size": artifact_path.stat().st_size and "sha256":
sha256_hex(args.artifact) (or pass artifact_path) before calling
write_stable_json; remove the artifact_bytes variable and its uses.
In `@src/core_main.rs`:
- Around line 30-35: The current check around args.get(1) silently falls back to
MacosUpdateArgs::App when a second argument exists but dmg_path does not end
with ".dmg"; change that to return an error instead of returning
MacosUpdateArgs::App. In the clause that binds dmg_path from args.get(1) (the
dmg_path variable and surrounding logic that currently returns
MacosUpdateArgs::App), detect the presence of a non-".dmg" second argument and
return a CLI/validation error (e.g., a clap::Error or a Result::Err with a clear
message like "invalid --update payload: expected .dmg") so malformed invocations
of --update do not silently select App mode. Ensure the error path is used only
when a second arg exists and is not a .dmg, preserving the original behavior
when no second arg is provided.
In `@src/flutter_ffi.rs`:
- Around line 2874-2880: The branch handling keys that start with
"verified-download-url-" currently returns only artifact.url from
verified_update_artifact_for_release_page_url, which drops the signed/verified
artifact metadata across the FFI boundary and forces re-verification later in
the "update-me" path; modify the branch in the code handling the
"verified-download-url-" key (the code that calls
verified_update_artifact_for_release_page_url) to return an opaque serialized
payload or token that contains the full verified artifact metadata (or instead
persist the signed sidecar next to the downloaded file and return a locator for
it), so the "update-me" handler can consume the original verified metadata
without re-downloading/re-verifying. Ensure the chosen payload is
serialized/deserialized safely across the FFI boundary and that code using the
"update-me" path reads that payload/token to find/verify the already-downloaded
artifact.
In `@src/hbbs_http/downloader.rs`:
- Around line 228-233: The GET response must be validated for a 2xx status
before streaming: after the timeout-handled send (the branch that sets response
from client.get(&url).send() inside the DOWNLOAD_REQUEST_TIMEOUT), check
response.status().is_success() (or call response.error_for_status()) and return
an Err/bail with a clear message including the status code or body snippet if
non-2xx; do this in the match arm that currently assigns response so
non-successful GETs are rejected immediately instead of being treated as a
successful download.
In `@src/lang/de.rs`:
- Around line 761-762: The two German i18n entries for the new update
verification flow — the keys "Verifying update" and "Please wait while {}
verifies the update." — currently have empty values; replace those empty strings
with sensible German fallback translations (e.g. a short label for "Verifying
update" and a sentence for the "Please wait..." message) so the UI doesn't show
blank text; update the tuple values in src/lang/de.rs for those keys accordingly
and ensure the placeholder {} is preserved in the German sentence.
In `@src/lang/eu.rs`:
- Around line 761-762: Update the Basque localization entry so the translation
key exactly matches the runtime lookup: replace the placeholder "{}" in the
tuple ("Please wait while {} verifies the update.", "") with the runtime
placeholder "{$appName}" so the key reads "Please wait while {$appName} verifies
the update." ensuring the lookup resolves correctly.
In `@src/lang/fa.rs`:
- Around line 761-762: The second translation key in the tuple pair ("Please
wait while {} verifies the update.", "") uses {} instead of the runtime-expected
placeholder {$appName}; update the key string to "Please wait while {$appName}
verifies the update." (leave the translation value as appropriate) so the dialog
lookup matches at runtime—modify the tuple entry in src/lang/fa.rs accordingly.
In `@src/lang/fi.rs`:
- Around line 761-762: The localization tuple with key "Please wait while {}
verifies the update." uses the wrong placeholder; update that key to use the
exact placeholder "{$appName}" so it matches calls to translate(...) (i.e.,
change the key string "Please wait while {} verifies the update." to "Please
wait while {$appName} verifies the update.") ensuring the translation lookup is
hit at runtime.
In `@src/lang/fr.rs`:
- Around line 761-762: The French translations map contains a mismatched key for
the update progress string—change the tuple key in src/lang/fr.rs from "Please
wait while {} verifies the update." to exactly "Please wait while {$appName}
verifies the update." so it matches the Flutter lookup used by
update_progress.dart (translate('Please wait while {$appName} verifies the
update.')); keep or update the French value as appropriate.
In `@src/lang/ge.rs`:
- Around line 761-762: The localization entry with the tuple ("Please wait while
{} verifies the update.", "") uses a generic {} placeholder that won't match the
lookup key; update that string to use the exact token {$appName} (i.e. change
"Please wait while {} verifies the update." to "Please wait while {$appName}
verifies the update.") so the localization lookup for {$appName} succeeds —
locate the tuple entry with that exact string and replace the placeholder
accordingly.
In `@src/lang/gu.rs`:
- Around line 761-762: The localization entry for "Verifying update" uses a
generic "{}" placeholder; replace the placeholder in the string "Please wait
while {} verifies the update." with the runtime key format "{$appName}" so the
lookup matches and the entry is used (update the string associated with
"Verifying update" to "Please wait while {$appName} verifies the update.").
In `@src/updater.rs`:
- Around line 143-153: Short-circuit the unsupported-platform path before
calling download_verified_update_artifact: after obtaining update_url and before
building UpdateArtifactQuery, call current_update_format(update_msi) (or
otherwise inspect the intended format) and if it indicates an
unsupported/unknown format (e.g., "unknown") log a debug/info message and return
the same no-op/manual-update outcome instead of proceeding; update the code
paths around current_software_update_url(), current_update_format(update_msi),
UpdateArtifactQuery, and download_verified_update_artifact() so unsupported
platforms don't attempt download_verified_update_artifact().
- Around line 698-715: The current copy_and_verify_update_artifact function uses
std::io::copy which writes the entire response before checking size; change it
to stream and stop immediately if more than expected_size is received by reading
in a loop (or wrapping reader with reader.take(expected_size + 1)) and writing
to file while tracking a running total, returning an error as soon as total >
expected_size; after the loop flush and call verify_file_sha256(temp_path,
expected_sha256) as before, and ensure you handle partial writes/cleanup
consistently (use the existing temp_path/file variables and keep the function
signature and verify_file_sha256 call intact).
---
Outside diff comments:
In `@src/platform/macos.rs`:
- Around line 1040-1047: update_from_dmg currently stages an extracted writable
.app in /tmp via extract_dmg and then calls
update_extracted/update_me_from_app_dir, which allows tampering; instead, change
update_from_dmg (and the similar block at lines ~1294-1340) to fail closed when
sidecar metadata/signature are missing after extraction OR (preferred) avoid
writable staging entirely by mounting the DMG and routing the update through the
mounted, verified read-only path: after extract_dmg/mount_dmg, validate sidecar
signature/metadata (use the existing verifier code you already have), and if
valid call update_me_from_app_dir/update_extracted with the mounted read-only
path (or return Err when verification fails); remove the codepath that copies
the bundle into /tmp and ensure update_extracted/update_me_from_app_dir accept a
mounted-path input rather than an extracted-temp path so the privileged swap
always consumes a verified read-only bundle.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 29de7256-952d-4d8f-a8c9-43a296571b0c
📒 Files selected for processing (68)
.github/workflows/flutter-build.yml.github/workflows/flutter-nightly.yml.github/workflows/flutter-tag.ymlflutter/lib/desktop/pages/desktop_home_page.dartflutter/lib/desktop/widgets/update_progress.dartres/generate_update_metadata.pyres/test_generate_update_metadata.pysrc/common.rssrc/core_main.rssrc/flutter_ffi.rssrc/hbbs_http/account.rssrc/hbbs_http/downloader.rssrc/hbbs_http/http_client.rssrc/hbbs_http/record_upload.rssrc/lang/ar.rssrc/lang/be.rssrc/lang/bg.rssrc/lang/ca.rssrc/lang/cn.rssrc/lang/cs.rssrc/lang/da.rssrc/lang/de.rssrc/lang/el.rssrc/lang/eo.rssrc/lang/es.rssrc/lang/et.rssrc/lang/eu.rssrc/lang/fa.rssrc/lang/fi.rssrc/lang/fr.rssrc/lang/ge.rssrc/lang/gu.rssrc/lang/he.rssrc/lang/hi.rssrc/lang/hr.rssrc/lang/hu.rssrc/lang/id.rssrc/lang/it.rssrc/lang/ja.rssrc/lang/ko.rssrc/lang/kz.rssrc/lang/lt.rssrc/lang/lv.rssrc/lang/ml.rssrc/lang/nb.rssrc/lang/nl.rssrc/lang/pl.rssrc/lang/pt_PT.rssrc/lang/ptbr.rssrc/lang/ro.rssrc/lang/ru.rssrc/lang/sc.rssrc/lang/sk.rssrc/lang/sl.rssrc/lang/sq.rssrc/lang/sr.rssrc/lang/sv.rssrc/lang/ta.rssrc/lang/template.rssrc/lang/th.rssrc/lang/tr.rssrc/lang/tw.rssrc/lang/uk.rssrc/lang/vi.rssrc/platform/macos.rssrc/platform/privileges_scripts/update.scptsrc/platform/windows.rssrc/updater.rs
df828a8 to
d972799
Compare
There was a problem hiding this comment.
Actionable comments posted: 23
♻️ Duplicate comments (2)
res/generate_update_metadata.py (1)
53-56:⚠️ Potential issue | 🟠 Major | ⚡ Quick winReject non-canonical asset URLs instead of collapsing empty path segments.
[part for part in parsed.path.split("/") if part]lets malformed paths like.../download/v1.4.6//artifact.exethrough by discarding the empty segment. That meansfragment/signcan still produce signed metadata thatverifylater rejects because the URL no longer matchesexpected_artifact_url(...).Proposed fix
- parts = [part for part in parsed.path.split("/") if part] + parts = parsed.path.split("/") expected_prefix = ["rustdesk", "rustdesk", "releases", "download"] - if len(parts) != 6 or parts[:4] != expected_prefix: + if ( + len(parts) != 7 + or parts[0] != "" + or parts[1:5] != expected_prefix + or not parts[5] + or not parts[6] + ): fail(f"artifact URL must be a RustDesk release asset URL: {url}") - release_id = parts[4] - file_name = parts[5] + release_id = parts[5] + file_name = parts[6]🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@res/generate_update_metadata.py` around lines 53 - 56, The current path normalization uses parts = [part for part in parsed.path.split("/") if part] which silently drops empty segments and accepts non-canonical URLs; change the validation in the URL-parsing logic (where parsed.path, parts, expected_prefix, and the fail(...) call are used) to reject any path containing empty segments instead of filtering them out—i.e., split parsed.path by "/" and if any segment is an empty string or the length/first four segments don't exactly match expected_prefix, call fail with the same message so malformed URLs like ...//artifact.exe are rejected and only canonical release asset URLs pass (ensure this affects any code that later compares to expected_artifact_url).src/flutter_ffi.rs (1)
2875-2881:⚠️ Potential issue | 🟠 MajorDon't discard the verified artifact metadata at this boundary.
This still returns only
artifact.url, so the later"update-me"flow has to re-resolve signed metadata from the network before it can trust the already-downloaded file. A user can therefore complete the verified download and still be unable to install while offline or rate-limited. Please pass back an opaque verified-artifact payload/token, or persist the signed sidecar locally and have"download-new-version"/"update-me"consume that instead of a bare URL.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/flutter_ffi.rs` around lines 2875 - 2881, The current branch that handles keys starting with "verified-download-url-" calls verified_update_artifact_for_release_page_url(&release_page_url) and then returns only artifact.url which discards the signed artifact metadata; instead modify this flow to return (or persist and return a token referencing) the full verified artifact payload/sidecar so downstream commands like "download-new-version" and "update-me" can consume the verified metadata without re-fetching it; specifically change the branch that handles keys starting with "verified-download-url-" to either serialize and return the complete artifact (or a stable opaque identifier referencing a locally persisted sidecar) returned by verified_update_artifact_for_release_page_url, and ensure "download-new-version"/"update-me" use that payload/token rather than only artifact.url.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/flutter-build.yml:
- Around line 293-303: Update the fragment generation steps in the "Generate
update metadata fragments" job so the artifact-url uses the current repository's
base URL instead of hardcoded rustdesk/rustdesk; replace the hardcoded
"https://github.com/rustdesk/rustdesk/releases/download/${TAG_NAME}/..." with a
URL built from ${{ github.server_url }}/${{ github.repository
}}/releases/download/${TAG_NAME}/... in the python3
res/generate_update_metadata.py fragment calls, and apply the same replacement
for the Windows/Sciter/macOS fragment steps (the other fragment command blocks
referenced at lines 486-495 and 867-869) so signed metadata points to the
current repo's release assets.
- Around line 901-904: The checkout step using actions/checkout (the step with
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5) should
explicitly disable credential persistence to avoid leaving a write-scoped token
in the workspace; update that step to include persist-credentials: false so the
job-level contents: write permission is not persisted to the checked-out
repository and downstream repo-controlled steps cannot access the token.
In `@res/test_generate_update_metadata.py`:
- Around line 179-183: The malformed-URL test matrix in
res/test_generate_update_metadata.py is missing the non-canonical double-slash
case; add an entry to the bad_url list like
f"{GITHUB_RELEASE}/v1.4.6//{artifact.name}" (alongside the existing entries in
the loop that builds bad_url) so the test covers the sign/verify mismatch path
with a stray extra slash.
In `@src/core_main.rs`:
- Around line 450-455: In the Err(err) arm that handles invalid `--update`
arguments in core_main.rs (the block currently logging via eprintln! and
log::error! and then doing `return None`), ensure the process returns a non-zero
exit status by replacing the `return None` with a call to std::process::exit(1)
(or alternatively propagate an error result instead of returning None) so
malformed update argument parsing causes a non-zero exit; keep the existing
logging but terminate with std::process::exit(1) to enforce the failure signal
to callers.
In `@src/hbbs_http/http_client.rs`:
- Around line 144-155: The call currently passes the resolved value
(danger_accept_invalid_cert) into both the "original" and "resolved" parameters
of create_http_client_with_url_ (and analogously
create_http_client_async_with_url), which lets force_strict_tls short-circuit
stale cached TLS policies; change the fifth argument to pass the raw cached
policy by calling get_cached_tls_accept_invalid_cert(tls_url) and keep
danger_accept_invalid_cert as the final argument so the function receives
(original_cached_option, resolved_effective_value); apply the same fix to
create_http_client_async_with_url.
In `@src/lang/cs.rs`:
- Around line 761-762: The two localization entries for "Verifying update" and
"Please wait while {} verifies the update." contain empty fallback values;
update their second elements to non-empty English strings (e.g., "Verifying
update" -> "Verifying update" and "Please wait while {} verifies the update." ->
"Please wait while {} verifies the update.") ensuring the "{}" placeholder
remains exactly as-is so runtime interpolation still works; modify the
corresponding tuples in src/lang/cs.rs where these keys appear.
In `@src/lang/da.rs`:
- Around line 761-762: The two Danish translation entries for the keys
"Verifying update" and "Please wait while {} verifies the update." are empty;
replace the empty strings with appropriate Danish text (e.g. "Bekræfter
opdatering" for "Verifying update" and "Vent venligst mens {} bekræfter
opdateringen." for the second) by editing the tuple entries in src/lang/da.rs
that contain those exact English keys.
In `@src/lang/el.rs`:
- Around line 761-762: The two Greek translations for the update-verification
strings are missing: replace the empty translation values for the tuple entries
with proper Greek text so the locale renders correctly; specifically update the
("Verifying update", "") and ("Please wait while {} verifies the update.", "")
entries in src/lang/el.rs to provide Greek translations (e.g., "Επαλήθευση
ενημέρωσης" and "Παρακαλώ περιμένετε ενώ το {} επαληθεύει την ενημέρωση." or
equivalent), keeping the original source strings intact.
In `@src/lang/eo.rs`:
- Around line 761-762: The two Esperanto translation entries for the
verification flow—specifically the tuple keys "Verifying update" and "Please
wait while {} verifies the update." in src/lang/eo.rs—are empty; replace the
empty strings with proper Esperanto translations (e.g., a concise translation
for "Verifying update" and a formatted string for "Please wait while {} verifies
the update." that preserves the {} placeholder) so the verification UI shows
non-empty localized text.
In `@src/lang/es.rs`:
- Line 762: The translation entry uses the wrong placeholder "{}" so it won't
match the runtime i18n key format; update the tuple entry that currently
contains "Please wait while {} verifies the update." to use the exact dialog
lookup placeholder "{$appName}" (i.e. "Please wait while {$appName} verifies the
update.") so the runtime will find this translation.
In `@src/lang/et.rs`:
- Line 762: Replace the placeholder "{}" in the translation string "Please wait
while {} verifies the update." with the exact runtime i18n placeholder
"{$appName}" so the key matches runtime lookup; update the tuple entry in the
translations list (the line containing that string) to use "Please wait while
{$appName} verifies the update." to avoid missed translation keys.
In `@src/lang/he.rs`:
- Line 762: The localization tuple for the Hebrew string entry currently uses a
generic runtime placeholder "{}"—update the key to use the runtime token
"{$appName}" so the lookup matches runtime substitution; locate the tuple
("Please wait while {} verifies the update.", "") in src/lang/he.rs (the Hebrew
localization entry) and replace the "{}" placeholder in the key with
"{$appName}" while leaving the translation value intact.
In `@src/lang/hi.rs`:
- Line 762: Replace the positional placeholder "{}" in the localization tuple
containing the string "Please wait while {} verifies the update." with the named
token "{$appName}" so the runtime key matches expected format (i.e., change
"Please wait while {} verifies the update." to "Please wait while {$appName}
verifies the update.").
In `@src/lang/hr.rs`:
- Line 762: Replace the placeholder token "{}" with the named token "{$appName}"
in the Croatian localization entry that currently reads "Please wait while {}
verifies the update." (the localization tuple string in src/lang/hr.rs) so the
runtime key matches the rest of the code that expects "{$appName}" as the app
name placeholder.
In `@src/lang/hu.rs`:
- Line 762: Update the translation tuple that currently uses the anonymous
placeholder ("Please wait while {} verifies the update.", "") to use the named
placeholder {$appName} so runtime lookup matches; replace "{}" with "{$appName}"
in that exact string literal (the tuple starting with "Please wait while {}
verifies the update.") so the runtime can substitute the app name.
In `@src/lang/sq.rs`:
- Around line 761-762: Two keys in the Albanian locale mapping—"Verifying
update" and "Please wait while {} verifies the update."—are set to empty
strings; replace those empty values with temporary fallback English strings
(e.g., "Verifying update" and "Please wait while {} verifies the update.") so
the verification dialog shows text for Albanian users until proper translations
are provided; locate the tuple entries in src/lang/sq.rs and update the
right-hand values for those two keys accordingly.
In `@src/lang/sr.rs`:
- Around line 761-762: The Serbian localization file contains empty translations
for the "Verifying update" entries; update src/lang/sr.rs so the tuple for
"Verifying update" and the tuple for "Please wait while {} verifies the update."
use the English fallback strings instead of empty ("") values (i.e., set the
right-hand elements to "Verifying update" and "Please wait while {} verifies the
update."). This keeps the UI visible until proper Serbian translations for those
keys are provided.
In `@src/lang/sv.rs`:
- Around line 761-762: The two translation tuples for the keys "Verifying
update" and "Please wait while {} verifies the update." have empty Swedish
fallbacks; update their second elements to non-empty strings (at minimum an
English fallback) or proper Swedish translations—e.g. replace the "" for the
tuple with "Verifying update" → "Verifying update" or Swedish like "Verifierar
uppdatering", and "Please wait while {} verifies the update." → "Please wait
while {} verifies the update." or Swedish like "Vänligen vänta medan {}
verifierar uppdateringen." so the status text is not blank when rendered.
In `@src/lang/ta.rs`:
- Around line 761-762: The two new Tamil localization entries ("Verifying
update", "") and ("Please wait while {} verifies the update.", "") should not be
empty; replace the empty strings with a fallback (e.g., the English text
"Verifying update" and "Please wait while {} verifies the update.") so the UI
shows a meaningful message until proper Tamil translations are provided; update
the tuples in src/lang/ta.rs where those keys appear.
In `@src/lang/th.rs`:
- Around line 761-762: Two translation entries currently have empty Thai values;
update the tuple entries for the keys "Verifying update" and "Please wait while
{} verifies the update." in src/lang/th.rs by replacing the empty strings with
temporary Thai fallback text (e.g., a short Thai phrase conveying "Verifying
update" and "Please wait while verifying the update") so the verification dialog
is not blank until proper translations are added.
In `@src/platform/macos.rs`:
- Around line 45-51: Tests share the process-wide OnceLock UPDATE_TEMP_DIR
causing parallel test interference; make the temp-dir injectable or serialized:
change code so get_update_temp_dir() can be overridden in tests (e.g. add a
test-only setter or accept a PathBuf argument) or protect tests with a global
test mutex, and update callers (create_update_temp_dmg_file(),
update_to_verified_dmg(), and any tests asserting get_update_temp_dir()) to use
the injectable/test-settable temp dir rather than relying on the static
UPDATE_TEMP_DIR OnceLock so each test gets an isolated directory or runs
serialized.
In `@src/platform/windows.rs`:
- Around line 3608-3610: The staging directory returned by
get_custom_client_staging_dir is not validated for being a symlink/junction
before copying; update the logic (either inside
handle_custom_client_staging_dir_before_update or immediately after
get_custom_client_staging_dir() and before copying) to detect and reject or
replace any symlink/junction: use platform-safe checks (e.g., symlink_metadata +
file_type().is_symlink() on Rust or Windows API to detect reparse points), and
if the directory exists and is a symlink/junction, remove it and recreate a
fresh directory with secure permissions (or fail early); ensure
remove_custom_client_staging_dir() behavior is complemented by this validation
so an attacker cannot redirect the elevated copy via a malicious
RustDeskCustomClientStaging junction.
In `@src/updater.rs`:
- Around line 272-286: The function
verified_update_artifact_for_release_page_url currently discards the
already-verified artifact returned by
verified_update_artifact_from_release_page_url and re-calls
verified_update_artifact_for_download_url_with_query, causing redundant refetch;
change it to use the artifact returned by
verified_update_artifact_from_release_page_url directly (do not build
download_query or call verified_update_artifact_for_download_url_with_query),
call cache_verified_update_artifact(&artifact) on that artifact and return it,
taking care to avoid variable shadowing when reusing the name "artifact".
---
Duplicate comments:
In `@res/generate_update_metadata.py`:
- Around line 53-56: The current path normalization uses parts = [part for part
in parsed.path.split("/") if part] which silently drops empty segments and
accepts non-canonical URLs; change the validation in the URL-parsing logic
(where parsed.path, parts, expected_prefix, and the fail(...) call are used) to
reject any path containing empty segments instead of filtering them out—i.e.,
split parsed.path by "/" and if any segment is an empty string or the
length/first four segments don't exactly match expected_prefix, call fail with
the same message so malformed URLs like ...//artifact.exe are rejected and only
canonical release asset URLs pass (ensure this affects any code that later
compares to expected_artifact_url).
In `@src/flutter_ffi.rs`:
- Around line 2875-2881: The current branch that handles keys starting with
"verified-download-url-" calls
verified_update_artifact_for_release_page_url(&release_page_url) and then
returns only artifact.url which discards the signed artifact metadata; instead
modify this flow to return (or persist and return a token referencing) the full
verified artifact payload/sidecar so downstream commands like
"download-new-version" and "update-me" can consume the verified metadata without
re-fetching it; specifically change the branch that handles keys starting with
"verified-download-url-" to either serialize and return the complete artifact
(or a stable opaque identifier referencing a locally persisted sidecar) returned
by verified_update_artifact_for_release_page_url, and ensure
"download-new-version"/"update-me" use that payload/token rather than only
artifact.url.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: e3dd8666-c0b7-4bf8-aea7-80a20056feb1
📒 Files selected for processing (69)
.github/workflows/flutter-build.yml.github/workflows/flutter-nightly.yml.github/workflows/flutter-tag.ymlflutter/lib/desktop/pages/desktop_home_page.dartflutter/lib/desktop/widgets/update_progress.dartlibs/hbb_commonres/generate_update_metadata.pyres/test_generate_update_metadata.pysrc/common.rssrc/core_main.rssrc/flutter_ffi.rssrc/hbbs_http/account.rssrc/hbbs_http/downloader.rssrc/hbbs_http/http_client.rssrc/hbbs_http/record_upload.rssrc/lang/ar.rssrc/lang/be.rssrc/lang/bg.rssrc/lang/ca.rssrc/lang/cn.rssrc/lang/cs.rssrc/lang/da.rssrc/lang/de.rssrc/lang/el.rssrc/lang/eo.rssrc/lang/es.rssrc/lang/et.rssrc/lang/eu.rssrc/lang/fa.rssrc/lang/fi.rssrc/lang/fr.rssrc/lang/ge.rssrc/lang/gu.rssrc/lang/he.rssrc/lang/hi.rssrc/lang/hr.rssrc/lang/hu.rssrc/lang/id.rssrc/lang/it.rssrc/lang/ja.rssrc/lang/ko.rssrc/lang/kz.rssrc/lang/lt.rssrc/lang/lv.rssrc/lang/ml.rssrc/lang/nb.rssrc/lang/nl.rssrc/lang/pl.rssrc/lang/pt_PT.rssrc/lang/ptbr.rssrc/lang/ro.rssrc/lang/ru.rssrc/lang/sc.rssrc/lang/sk.rssrc/lang/sl.rssrc/lang/sq.rssrc/lang/sr.rssrc/lang/sv.rssrc/lang/ta.rssrc/lang/template.rssrc/lang/th.rssrc/lang/tr.rssrc/lang/tw.rssrc/lang/uk.rssrc/lang/vi.rssrc/platform/macos.rssrc/platform/privileges_scripts/update.scptsrc/platform/windows.rssrc/updater.rs
d972799 to
9b1bbe5
Compare
There was a problem hiding this comment.
Actionable comments posted: 12
♻️ Duplicate comments (8)
.github/workflows/flutter-build.yml (3)
833-836:⚠️ Potential issue | 🟠 Major | ⚡ Quick winDisable credential persistence for checkout.
This job has
permissions: contents: writebut the checkout step doesn't setpersist-credentials: false. The write-scoped token remains accessible to subsequentcargo/pythonsteps that execute repo-controlled code. The latersoftprops/action-gh-releasestep uses the job token directly and doesn't need persisted credentials.Suggested fix
- name: Checkout source code uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: + persist-credentials: false submodules: recursive🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/flutter-build.yml around lines 833 - 836, Update the "Checkout source code" actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 step to add with: persist-credentials: false so the job token is not left in the workspace; locate the checkout step (name: "Checkout source code" / uses: actions/checkout@34e1148...) and add the persist-credentials: false key alongside submodules: recursive.
810-815:⚠️ Potential issue | 🟠 Major | ⚡ Quick winGate macOS metadata upload on code-signing availability.
The upload step runs whenever Ed25519 metadata signing is enabled, but doesn't verify the DMG was actually codesigned. If
MACOS_P12_BASE64is unset, the unsigned DMG (created at line 771) still matches the expected path, so this step uploads an unsigned artifact that will pass metadata verification but fail client-sidecodesign --verify.Suggested fix
- name: Upload signed macOS DMG - if: env.UPLOAD_ARTIFACT == 'true' && env.PUBLISH_UPDATE_METADATA == 'true' && env.UPDATE_METADATA_SIGNING_ENABLED == 'true' + if: env.UPLOAD_ARTIFACT == 'true' && env.PUBLISH_UPDATE_METADATA == 'true' && env.UPDATE_METADATA_SIGNING_ENABLED == 'true' && env.MACOS_P12_BASE64 != '' uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/flutter-build.yml around lines 810 - 815, The "Upload signed macOS DMG" step can upload an unsigned DMG when Ed25519 signing is enabled but macOS code signing material is missing; update the step's conditional to require the macOS P12 secret is present (e.g. check env.MACOS_P12_BASE64 is non-empty) in addition to the existing checks (env.UPLOAD_ARTIFACT, env.PUBLISH_UPDATE_METADATA, env.UPDATE_METADATA_SIGNING_ENABLED) so the artifact path rustdesk-${{ env.VERSION }}-${{ matrix.job.arch }}.dmg is only uploaded when code signing actually occurred.
905-915:⚠️ Potential issue | 🟠 Major | ⚡ Quick winBuild metadata URLs from the current repository.
The fragment commands hardcode
rustdesk/rustdesk, but this workflow publishes release assets to the current repository. In a fork or manual-release scenario, the signed metadata will contain URLs pointing to assets that don't exist atrustdesk/rustdesk.Suggested fix
- name: Generate update metadata fragments shell: bash env: VERSION: ${{ env.VERSION }} TAG_NAME: ${{ env.TAG_NAME }} + BASE_RELEASE_URL: ${{ github.server_url }}/${{ github.repository }}/releases/download/${{ env.TAG_NAME }} run: | - python res/generate_update_metadata.py fragment --artifact "./artifacts/windows-x86_64/rustdesk-${VERSION}-x86_64.exe" --artifact-url "https://github.com/rustdesk/rustdesk/releases/download/${TAG_NAME}/rustdesk-${VERSION}-x86_64.exe" --platform windows --arch x86_64 --format exe --fragment-out ./fragments/windows-flutter-x86_64-exe.json - python res/generate_update_metadata.py fragment --artifact "./artifacts/windows-x86_64/rustdesk-${VERSION}-x86_64.msi" --artifact-url "https://github.com/rustdesk/rustdesk/releases/download/${TAG_NAME}/rustdesk-${VERSION}-x86_64.msi" --platform windows --arch x86_64 --format msi --fragment-out ./fragments/windows-flutter-x86_64-msi.json - python res/generate_update_metadata.py fragment --artifact "./artifacts/windows-x86/rustdesk-${VERSION}-x86-sciter.exe" --artifact-url "https://github.com/rustdesk/rustdesk/releases/download/${TAG_NAME}/rustdesk-${VERSION}-x86-sciter.exe" --platform windows --arch x86 --format exe --fragment-out ./fragments/windows-sciter-x86-exe.json - python res/generate_update_metadata.py fragment --artifact "./artifacts/macos-aarch64/rustdesk-${VERSION}-aarch64.dmg" --artifact-url "https://github.com/rustdesk/rustdesk/releases/download/${TAG_NAME}/rustdesk-${VERSION}-aarch64.dmg" --platform macos --arch aarch64 --format dmg --fragment-out ./fragments/macos-aarch64-dmg.json - python res/generate_update_metadata.py fragment --artifact "./artifacts/macos-x86_64/rustdesk-${VERSION}-x86_64.dmg" --artifact-url "https://github.com/rustdesk/rustdesk/releases/download/${TAG_NAME}/rustdesk-${VERSION}-x86_64.dmg" --platform macos --arch x86_64 --format dmg --fragment-out ./fragments/macos-x86_64-dmg.json + python res/generate_update_metadata.py fragment --artifact "./artifacts/windows-x86_64/rustdesk-${VERSION}-x86_64.exe" --artifact-url "${BASE_RELEASE_URL}/rustdesk-${VERSION}-x86_64.exe" --platform windows --arch x86_64 --format exe --fragment-out ./fragments/windows-flutter-x86_64-exe.json + python res/generate_update_metadata.py fragment --artifact "./artifacts/windows-x86_64/rustdesk-${VERSION}-x86_64.msi" --artifact-url "${BASE_RELEASE_URL}/rustdesk-${VERSION}-x86_64.msi" --platform windows --arch x86_64 --format msi --fragment-out ./fragments/windows-flutter-x86_64-msi.json + python res/generate_update_metadata.py fragment --artifact "./artifacts/windows-x86/rustdesk-${VERSION}-x86-sciter.exe" --artifact-url "${BASE_RELEASE_URL}/rustdesk-${VERSION}-x86-sciter.exe" --platform windows --arch x86 --format exe --fragment-out ./fragments/windows-sciter-x86-exe.json + python res/generate_update_metadata.py fragment --artifact "./artifacts/macos-aarch64/rustdesk-${VERSION}-aarch64.dmg" --artifact-url "${BASE_RELEASE_URL}/rustdesk-${VERSION}-aarch64.dmg" --platform macos --arch aarch64 --format dmg --fragment-out ./fragments/macos-aarch64-dmg.json + python res/generate_update_metadata.py fragment --artifact "./artifacts/macos-x86_64/rustdesk-${VERSION}-x86_64.dmg" --artifact-url "${BASE_RELEASE_URL}/rustdesk-${VERSION}-x86_64.dmg" --platform macos --arch x86_64 --format dmg --fragment-out ./fragments/macos-x86_64-dmg.json🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/flutter-build.yml around lines 905 - 915, The fragment generation hardcodes "rustdesk/rustdesk" in artifact URLs causing signed metadata to point to the wrong repo; update the workflow step to use the current repository variable (e.g. add env REPOSITORY: ${{ github.repository }} or use $GITHUB_REPOSITORY) and substitute "rustdesk/rustdesk" with that variable in every python res/generate_update_metadata.py --artifact-url argument (refer to the Generate update metadata fragments step and the individual commands invoking generate_update_metadata.py).src/core_main.rs (1)
450-455:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winReturn a non-zero exit code for invalid
--updatearguments.This branch logs the parse failure and then falls through to
return None, so malformed update commands still look successful to callers.Suggested fix
Err(err) => { eprintln!("Invalid update arguments: {}", err); log::error!("Invalid update arguments: {}", err); + std::process::exit(2); } } return None;🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/core_main.rs` around lines 450 - 455, The Err(err) branch currently logs the parse failure (eprintln! and log::error!) and then falls through to return None, leaving callers unaware of the failure; change the control flow so malformed `--update` arguments produce a non-zero exit status instead of returning None — for example, inside the Err(err) arm (the block with Err(err), eprintln! and log::error!) either call std::process::exit(1) immediately or return an error/Some non-zero exit-code value consistent with the surrounding function signature so the caller observes a failure rather than a successful None.src/lang/th.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winEmpty translation strings will display blank UI text for Thai users.
Lines 761 and 762 provide empty values for the new update verification messages. Until proper Thai translations are available, use the English keys as temporary placeholders to prevent blank UI text.
🌐 Suggested temporary fix
- ("Verifying update", ""), - ("Please wait while {} verifies the update.", ""), + ("Verifying update", "Verifying update"), + ("Please wait while {} verifies the update.", "Please wait while {} verifies the update."),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/th.rs` around lines 761 - 762, The two Thai translation entries for the update verification messages currently have empty values; replace the empty strings for the keys "Verifying update" and "Please wait while {} verifies the update." with the English phrases as temporary placeholders so the UI won't show blank text—locate the tuple entries in th.rs where those keys appear and set their second element to the English key text until proper Thai translations are provided.src/lang/da.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winEmpty translation strings will display blank UI text for Danish users.
Lines 761 and 762 provide empty values for the new update verification messages. Until proper Danish translations are available, use the English keys as temporary placeholders to prevent blank UI text.
🌐 Suggested temporary fix
- ("Verifying update", ""), - ("Please wait while {} verifies the update.", ""), + ("Verifying update", "Verifying update"), + ("Please wait while {} verifies the update.", "Please wait while {} verifies the update."),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/da.rs` around lines 761 - 762, Replace the empty Danish translation values for the keys "Verifying update" and "Please wait while {} verifies the update." with their English text as temporary placeholders; locate the translation entries that currently read ("Verifying update", "") and ("Please wait while {} verifies the update.", "") and set the right-hand strings to "Verifying update" and "Please wait while {} verifies the update." respectively so the UI shows non-blank text until proper Danish translations are provided.src/lang/sv.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winDon't ship empty Swedish strings for the verification flow.
Lines 761 and 762 map to empty strings, which will render blank UI text during update verification for Swedish users. Use English fallbacks until proper Swedish translations are provided.
📝 Suggested fix
- ("Verifying update", ""), - ("Please wait while {} verifies the update.", ""), + ("Verifying update", "Verifying update"), + ("Please wait while {} verifies the update.", "Please wait while {} verifies the update."),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/sv.rs` around lines 761 - 762, The Swedish localization currently has two empty translations for the keys ("Verifying update", "") and ("Please wait while {} verifies the update.", "") in src/lang/sv.rs; replace the empty strings with the English fallback text ("Verifying update", "Please wait while {} verifies the update.") so the UI shows non-blank messages for Swedish users until proper Swedish translations are provided.src/lang/sr.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winDon't ship empty Serbian strings for the verification flow.
Lines 761 and 762 map to empty strings, which will render blank UI text during update verification for Serbian users. Use English fallbacks until proper Serbian translations are provided.
📝 Suggested fix
- ("Verifying update", ""), - ("Please wait while {} verifies the update.", ""), + ("Verifying update", "Verifying update"), + ("Please wait while {} verifies the update.", "Please wait while {} verifies the update."),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/sr.rs` around lines 761 - 762, The Serbian localization contains empty translations for the update verification messages (the tuple entries for "Verifying update" and "Please wait while {} verifies the update."); update those entries in src/lang/sr.rs to use the English fallback strings (e.g., "Verifying update" and "Please wait while {} verifies the update.") or supply proper Serbian translations so the UI is not blank during verification; ensure you modify the tuples matching those exact source keys.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@res/generate_update_metadata.py`:
- Around line 275-282: The except Exception block that catches errors from
main() currently does `raise SystemExit(1)` which loses the original exception
context; update the raise to preserve the chain by using `raise SystemExit(1)
from error` (or explicitly suppress with `from None` if intentional) so the
original exception information from main() is retained; locate the top-level
guard around main() and modify the SystemExit raise accordingly.
In `@src/core_main.rs`:
- Around line 33-35: The check rejecting DMG files is case-sensitive; update the
validation that uses dmg_path (in core_main.rs) to compare the extension
case-insensitively — e.g., normalize dmg_path (or its extension via
Path::extension) to lowercase before testing for ".dmg" — and return the same
Err(...) only if the lowercased/normalized extension is not "dmg".
In `@src/lang/ptbr.rs`:
- Around line 761-762: The two localization entries for "Verifying update" and
"Please wait while {} verifies the update." currently map to empty strings and
will render blank UI; update the mapping in src/lang/ptbr.rs by replacing the
empty values for the keys "Verifying update" and "Please wait while {} verifies
the update." with Portuguese translations (e.g., "Verificando atualização" and
"Aguarde enquanto {} verifica a atualização.") so users see proper text during
update verification or alternatively implement an explicit fallback to English
if translation is unavailable.
In `@src/lang/ro.rs`:
- Around line 761-762: Update the Romanian localization in src/lang/ro.rs by
replacing the empty translations for the keys "Verifying update" and "Please
wait while {} verifies the update." with appropriate Romanian strings (e.g.,
"Verificarea actualizării" and "Vă rugăm să așteptați în timp ce {} verifică
actualizarea."). Ensure the exact key text remains unchanged and only the
right-hand translation values are modified so the lookup uses the Romanian text
instead of rendering blank UI.
In `@src/lang/ru.rs`:
- Around line 761-762: The two localization entries "Verifying update" and
"Please wait while {} verifies the update." are mapped to empty strings causing
blank UI text; update the Russian resource in src/lang/ru.rs by providing proper
Russian translations for those keys (e.g. a concise heading for "Verifying
update" and a sentence with the {} placeholder preserved for "Please wait while
{} verifies the update."), or ensure the code falls back to English by replacing
the empty values with the English defaults if translations are not yet
available.
In `@src/lang/sc.rs`:
- Around line 761-762: The two localization entries for "Verifying update" and
"Please wait while {} verifies the update." currently map to empty strings in
the Sardinian locale; update the mapping in lang/sc.rs so they are not blank by
either providing proper Sardinian translations or assigning English fallback
text (e.g., "Verifying update" and "Please wait while {} verifies the update.")
for those keys; locate the tuples matching those exact source strings in the
locale array/map and replace the empty string values with the chosen
translations so the update verification UI shows readable text.
In `@src/lang/sk.rs`:
- Around line 761-762: The two localization entries for "Verifying update" and
"Please wait while {} verifies the update." are mapped to empty strings; update
the array entries in src/lang/sk.rs by replacing the empty values with proper
Slovak translations (e.g., "Overovanie aktualizácie" and "Počkajte, kým {} overí
aktualizáciu.") or, if translations aren't ready, set them to the English
fallback texts so the UI shows "Verifying update" and "Please wait while {}
verifies the update." instead of blank strings.
In `@src/lang/sl.rs`:
- Around line 761-762: The two localization entries for the Slovenian file (the
tuple keys "Verifying update" and "Please wait while {} verifies the update.")
are mapped to empty strings; replace those empty values with either proper
Slovenian translations or an English fallback string so the UI shows text during
update verification (update the tuples in src/lang/sl.rs corresponding to those
keys). Ensure the second string preserves the placeholder "{}" exactly so the
runtime formatting (the message produced by the update verification flow)
continues to work correctly.
In `@src/lang/tw.rs`:
- Around line 761-762: Replace the empty Traditional Chinese translation values
for the localization keys "Verifying update" and "Please wait while {} verifies
the update." with proper Traditional Chinese strings (preserve the placeholder
{} exactly in the second string); update the tuple entries where those keys
appear so the UI shows meaningful verification status text (e.g., provide
translations like "正在驗證更新" and "請稍候,{} 正在驗證更新。") ensuring punctuation and
spacing match project conventions.
In `@src/lang/uk.rs`:
- Around line 761-762: The two translation entries ("Verifying update", "") and
("Please wait while {} verifies the update.", "") in src/lang/uk.rs are empty
and will render blank UI; replace the empty strings with proper Ukrainian
translations, preserving the placeholder {} in the second entry (e.g., translate
"Verifying update" and "Please wait while {} verifies the update." into
Ukrainian) so the status and progress message display correctly during update
verification.
In `@src/lang/vi.rs`:
- Around line 761-762: The two localization entries ("Verifying update", "") and
("Please wait while {} verifies the update.", "") in src/lang/vi.rs are empty
and will render blank UI during update verification; replace the empty strings
with proper Vietnamese translations (e.g., a concise translation for "Verifying
update" and a parameterized translation for "Please wait while {} verifies the
update.") so that the functions/keys that use these tuples show meaningful
status text during verification.
In `@src/platform/macos.rs`:
- Around line 936-959: The AppleScript embodied in the update_body variable
duplicates the privileged update logic found in update.scpt, risking drift;
refactor by extracting the shared shell sequence (the sh string built from
check_source, kill_others, prepare_verified, prepare_swap_paths, copy_files,
cleanup_verified, etc.) into a single reusable string or function that both the
non-daemon AppleScript path (update_body) and the update.scpt loader consume,
then have update_body interpolate or call that single source instead of
rebuilding the shell commands inline.
---
Duplicate comments:
In @.github/workflows/flutter-build.yml:
- Around line 833-836: Update the "Checkout source code"
actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 step to add with:
persist-credentials: false so the job token is not left in the workspace; locate
the checkout step (name: "Checkout source code" / uses:
actions/checkout@34e1148...) and add the persist-credentials: false key
alongside submodules: recursive.
- Around line 810-815: The "Upload signed macOS DMG" step can upload an unsigned
DMG when Ed25519 signing is enabled but macOS code signing material is missing;
update the step's conditional to require the macOS P12 secret is present (e.g.
check env.MACOS_P12_BASE64 is non-empty) in addition to the existing checks
(env.UPLOAD_ARTIFACT, env.PUBLISH_UPDATE_METADATA,
env.UPDATE_METADATA_SIGNING_ENABLED) so the artifact path rustdesk-${{
env.VERSION }}-${{ matrix.job.arch }}.dmg is only uploaded when code signing
actually occurred.
- Around line 905-915: The fragment generation hardcodes "rustdesk/rustdesk" in
artifact URLs causing signed metadata to point to the wrong repo; update the
workflow step to use the current repository variable (e.g. add env REPOSITORY:
${{ github.repository }} or use $GITHUB_REPOSITORY) and substitute
"rustdesk/rustdesk" with that variable in every python
res/generate_update_metadata.py --artifact-url argument (refer to the Generate
update metadata fragments step and the individual commands invoking
generate_update_metadata.py).
In `@src/core_main.rs`:
- Around line 450-455: The Err(err) branch currently logs the parse failure
(eprintln! and log::error!) and then falls through to return None, leaving
callers unaware of the failure; change the control flow so malformed `--update`
arguments produce a non-zero exit status instead of returning None — for
example, inside the Err(err) arm (the block with Err(err), eprintln! and
log::error!) either call std::process::exit(1) immediately or return an
error/Some non-zero exit-code value consistent with the surrounding function
signature so the caller observes a failure rather than a successful None.
In `@src/lang/da.rs`:
- Around line 761-762: Replace the empty Danish translation values for the keys
"Verifying update" and "Please wait while {} verifies the update." with their
English text as temporary placeholders; locate the translation entries that
currently read ("Verifying update", "") and ("Please wait while {} verifies the
update.", "") and set the right-hand strings to "Verifying update" and "Please
wait while {} verifies the update." respectively so the UI shows non-blank text
until proper Danish translations are provided.
In `@src/lang/sr.rs`:
- Around line 761-762: The Serbian localization contains empty translations for
the update verification messages (the tuple entries for "Verifying update" and
"Please wait while {} verifies the update."); update those entries in
src/lang/sr.rs to use the English fallback strings (e.g., "Verifying update" and
"Please wait while {} verifies the update.") or supply proper Serbian
translations so the UI is not blank during verification; ensure you modify the
tuples matching those exact source keys.
In `@src/lang/sv.rs`:
- Around line 761-762: The Swedish localization currently has two empty
translations for the keys ("Verifying update", "") and ("Please wait while {}
verifies the update.", "") in src/lang/sv.rs; replace the empty strings with the
English fallback text ("Verifying update", "Please wait while {} verifies the
update.") so the UI shows non-blank messages for Swedish users until proper
Swedish translations are provided.
In `@src/lang/th.rs`:
- Around line 761-762: The two Thai translation entries for the update
verification messages currently have empty values; replace the empty strings for
the keys "Verifying update" and "Please wait while {} verifies the update." with
the English phrases as temporary placeholders so the UI won't show blank
text—locate the tuple entries in th.rs where those keys appear and set their
second element to the English key text until proper Thai translations are
provided.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 076ffd2e-02ad-4204-bb6b-8f6a46d79bb4
📒 Files selected for processing (69)
.github/workflows/flutter-build.yml.github/workflows/flutter-nightly.yml.github/workflows/flutter-tag.ymlflutter/lib/desktop/pages/desktop_home_page.dartflutter/lib/desktop/widgets/update_progress.dartlibs/hbb_commonres/generate_update_metadata.pyres/test_generate_update_metadata.pysrc/common.rssrc/core_main.rssrc/flutter_ffi.rssrc/hbbs_http/account.rssrc/hbbs_http/downloader.rssrc/hbbs_http/http_client.rssrc/hbbs_http/record_upload.rssrc/lang/ar.rssrc/lang/be.rssrc/lang/bg.rssrc/lang/ca.rssrc/lang/cn.rssrc/lang/cs.rssrc/lang/da.rssrc/lang/de.rssrc/lang/el.rssrc/lang/eo.rssrc/lang/es.rssrc/lang/et.rssrc/lang/eu.rssrc/lang/fa.rssrc/lang/fi.rssrc/lang/fr.rssrc/lang/ge.rssrc/lang/gu.rssrc/lang/he.rssrc/lang/hi.rssrc/lang/hr.rssrc/lang/hu.rssrc/lang/id.rssrc/lang/it.rssrc/lang/ja.rssrc/lang/ko.rssrc/lang/kz.rssrc/lang/lt.rssrc/lang/lv.rssrc/lang/ml.rssrc/lang/nb.rssrc/lang/nl.rssrc/lang/pl.rssrc/lang/pt_PT.rssrc/lang/ptbr.rssrc/lang/ro.rssrc/lang/ru.rssrc/lang/sc.rssrc/lang/sk.rssrc/lang/sl.rssrc/lang/sq.rssrc/lang/sr.rssrc/lang/sv.rssrc/lang/ta.rssrc/lang/template.rssrc/lang/th.rssrc/lang/tr.rssrc/lang/tw.rssrc/lang/uk.rssrc/lang/vi.rssrc/platform/macos.rssrc/platform/privileges_scripts/update.scptsrc/platform/windows.rssrc/updater.rs
9b1bbe5 to
eae0cf0
Compare
There was a problem hiding this comment.
Pull request overview
This PR refactors RustDesk’s update system to use signed release metadata as the source of truth for update artifact URLs, sizes, and SHA256s, and unifies verification + download behavior across auto/manual updates and macOS DMG installs. It also extends CI to generate/sign/verify update metadata and publish it alongside release artifacts.
Changes:
- Replace GitHub-asset-digest based validation with signed metadata verification (artifact URL/size/SHA256) and apply strict TLS + bounded timeouts to update downloads.
- Rework Windows/macOS update install flows to verify artifacts (SHA256; plus additional path-safety hardening) before invoking installers; improve macOS DMG install flow and AppleScript privileged install logic.
- Add update-metadata generation/signing/verifying tooling + tests, and update GitHub Actions workflows to publish signed update metadata and signed artifacts.
Reviewed changes
Copilot reviewed 69 out of 69 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
src/updater.rs |
Fetch/verify signed update metadata, download artifacts with size/SHA256 verification, strict TLS + timeouts, and cache verified artifacts. |
src/platform/windows.rs |
Add verified update entrypoints, safer staging-dir handling, reparse-point protections, and SHA256 verification using locked file handles. |
src/platform/privileges_scripts/update.scpt |
Update macOS privileged install script to stage/swap bundles more safely and clean up temp paths via trap. |
src/platform/macos.rs |
Add verified DMG update paths (sidecar verification + SHA256), safer temp dir handling, and improved DMG mount/attach error handling. |
src/lang/ar.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/be.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/bg.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/ca.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/cn.rs |
Add translated “Verifying update” strings (Chinese). |
src/lang/cs.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/da.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/de.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/el.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/eo.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/es.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/et.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/eu.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/fa.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/fi.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/fr.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/ge.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/gu.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/he.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/hi.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/hr.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/hu.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/id.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/it.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/ja.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/ko.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/kz.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/lt.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/lv.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/ml.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/nb.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/nl.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/pl.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/pt_PT.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/ptbr.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/ro.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/ru.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/sc.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/sk.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/sl.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/sq.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/sr.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/sv.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/ta.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/template.rs |
Add new translation keys to template. |
src/lang/th.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/tr.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/tw.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/uk.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/lang/vi.rs |
Add “Verifying update” strings (fallback-to-English placeholders). |
src/hbbs_http/record_upload.rs |
Update HTTP client creation to pass the new strict-TLS flag parameter. |
src/hbbs_http/http_client.rs |
Add force_strict_tls override to sync/async HTTP client builders and tests. |
src/hbbs_http/downloader.rs |
Add bounded timeouts + strict TLS for downloads, plus improved cancellation warmup behavior and tests. |
src/hbbs_http/account.rs |
Update HTTP client creation to pass the new strict-TLS flag parameter. |
src/flutter_ffi.rs |
Update Flutter-facing update flow to resolve verified download URLs and verify artifacts before install; add error event plumbing + tests. |
src/core_main.rs |
Add macOS --update argument parsing for verified DMG sidecars vs legacy DMG updates; add tests. |
src/common.rs |
Harden/validate update URLs, derive metadata/signature URLs, and refactor update URL storage/clearing logic with tests. |
res/test_generate_update_metadata.py |
New Python unit tests for metadata fragment/sign/verify script behavior. |
res/generate_update_metadata.py |
New Python CLI to generate fragments, sign metadata, and verify metadata/artifacts with Ed25519. |
flutter/lib/desktop/widgets/update_progress.dart |
Update UI update/download flow to use verified download URLs, improve cancellation, and centralize error presentation. |
flutter/lib/desktop/pages/desktop_home_page.dart |
Adapt update button handler to async update flow. |
.github/workflows/flutter-tag.yml |
Add dispatch input for upload tag and enable metadata publishing for tagged builds. |
.github/workflows/flutter-nightly.yml |
Explicitly disable metadata publishing for nightly builds. |
.github/workflows/flutter-build.yml |
Add CI pipeline to build/upload signed artifacts, generate/sign/verify update metadata, and publish a signed update release. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Actionable comments posted: 13
♻️ Duplicate comments (6)
src/lang/sq.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAvoid empty localized values for verification status text.
Both new strings are
"", which can leave this update-verification UI text blank for Albanian users. Please use a temporary fallback (e.g., English) until proper translations are added.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/sq.rs` around lines 761 - 762, Two Albanian localization entries currently have empty values—specifically the tuples ("Verifying update", "") and ("Please wait while {} verifies the update.", "") in src/lang/sq.rs—so replace the empty strings with temporary English fallback text (e.g., "Verifying update" and "Please wait while {} verifies the update.") until proper Albanian translations are provided; update the corresponding tuples in the localization array or map so the UI shows the fallback instead of blank text.src/lang/th.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAvoid empty values for the new verification status entries.
These Thai strings are empty, so update-verification messages can appear blank. Add fallback strings until localized text is ready.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/th.rs` around lines 761 - 762, The two new tuples ("Verifying update", "") and ("Please wait while {} verifies the update.", "") in lang/th.rs contain empty translations; replace the empty string values with appropriate fallback strings (e.g., use the original English text or a short Thai placeholder) so update-verification messages are not blank — update the entries for "Verifying update" and "Please wait while {} verifies the update." with non-empty fallback strings until proper Thai localizations are provided.src/lang/sr.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winDon’t ship empty values for verification flow strings.
These two new Serbian entries are empty, so the verification dialog may show blank text. Add fallback text until translation is available.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/sr.rs` around lines 761 - 762, The two Serbian localization tuples for the verification flow ("Verifying update" and "Please wait while {} verifies the update.") currently have empty values; replace those empty strings with appropriate fallback text (e.g., English strings or a temporary Serbian fallback) so the verification dialog doesn't render blank — update the value entries paired with the keys "Verifying update" and "Please wait while {} verifies the update." in the sr.rs localization list to non-empty fallback strings.src/lang/ta.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winUse fallback text instead of empty strings for update verification labels.
Both new Tamil entries are empty; this can leave verification progress text blank in the UI.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/ta.rs` around lines 761 - 762, The two Tamil translation entries for the source strings "Verifying update" and "Please wait while {} verifies the update." are empty; replace the empty strings with a sensible fallback (e.g., the original English text or a short Tamil placeholder) so the UI shows text during verification. Locate the tuples in src/lang/ta.rs (the translation list containing ("Verifying update", "") and ("Please wait while {} verifies the update.", "")) and update the second element of each tuple to a non-empty fallback string.src/lang/sv.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winProvide non-empty fallback strings for these new keys.
"Verifying update"and"Please wait while {} verifies the update."are empty, which can produce blank UI text in Swedish during verification.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/sv.rs` around lines 761 - 762, Fill the empty fallback strings for the translation keys "Verifying update" and "Please wait while {} verifies the update." by replacing the "" values with Swedish translations (e.g. "Verifierar uppdatering" and "Vänligen vänta medan {} verifierar uppdateringen.") so the tuple entries for those keys return non-empty UI text..github/workflows/flutter-build.yml (1)
826-886:⚠️ Potential issue | 🟠 Major | ⚡ Quick winGate metadata publication on macOS signing availability too.
build-for-macOSonly uploadsmacos-*-dmgwhenenv.MACOS_P12_BASE64 != ''on Line 811, but this job always tries to download both DMGs whenever Ed25519 metadata signing is enabled. If the metadata key is configured without the macOS cert, the DMG uploads are skipped, the direct DMG publish step is also suppressed, and this job fails on the first download. Mirror the macOS-signing precondition in the jobif:(or emit it fromdetect-update-metadata-signing) so the release path stays internally consistent.🔧 Minimal fix
publish-signed-update-metadata: needs: [detect-update-metadata-signing, build-for-windows-flutter, build-for-windows-sciter, build-for-macOS] runs-on: ubuntu-22.04 - if: needs.detect-update-metadata-signing.outputs.upload_artifact_enabled == 'true' && needs.detect-update-metadata-signing.outputs.publish_update_metadata_enabled == 'true' && needs.detect-update-metadata-signing.outputs.update_metadata_signing_enabled == 'true' + if: needs.detect-update-metadata-signing.outputs.upload_artifact_enabled == 'true' && needs.detect-update-metadata-signing.outputs.publish_update_metadata_enabled == 'true' && needs.detect-update-metadata-signing.outputs.update_metadata_signing_enabled == 'true' && env.MACOS_P12_BASE64 != ''🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/flutter-build.yml around lines 826 - 886, The publish-signed-update-metadata job tries to download macOS DMGs even when build-for-macOS omitted them due to missing macOS cert; update the job's gating to require the macOS signing precondition used in build-for-macOS (check env.MACOS_P12_BASE64 != '' or add a new output from detect-update-metadata-signing like macos_signing_enabled) so the publish-signed-update-metadata job only runs when macOS artifacts were actually uploaded; modify the job named publish-signed-update-metadata's if: expression to include this macOS signing check (or emit and use a detect-update-metadata-signing output) to keep the release path consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/core_main.rs`:
- Around line 402-460: The error branches for MacOS update handling currently
only log/print errors and then fall through to returning None, causing
successful process exit; modify the Err arms for
platform::update_from_verified_dmg_sidecar (in the MacosUpdateArgs::VerifiedDmg
match), platform::update_from_dmg (LegacyDmg), platform::update_me (App), and
the parse_macos_update_args Err branch so that after logging/printing they call
std::process::exit with a non-zero code (e.g., exit(1)) to propagate failure to
the caller; ensure each Err arm uses the same non-zero exit path so scripted
invocations can detect update failures.
In `@src/hbbs_http/http_client.rs`:
- Around line 144-155: The code currently keeps is_tls_type_cached=true even
when force_strict_tls flips a cached policy (cached_danger_accept_invalid_cert)
to the opposite value (danger_accept_invalid_cert), causing the strict probe to
be skipped; update the logic after calling get_cached_tls_accept_invalid_cert
and resolve_danger_accept_invalid_cert so that if
cached_danger_accept_invalid_cert.is_some() and
cached_danger_accept_invalid_cert != danger_accept_invalid_cert you set
is_tls_type_cached = false (i.e., treat this override as an uncached TLS probe),
and apply the identical change in both create_http_client_with_url_ and
create_http_client_async_with_url to ensure the async path behaves the same.
In `@src/lang/es.rs`:
- Around line 761-762: The two Spanish translations for the keys "Verifying
update" and "Please wait while {} verifies the update." are empty; update their
mapped values in src/lang/es.rs to non-empty Spanish strings (or at least an
English fallback) while preserving the "{}" placeholder exactly; e.g., provide a
short Spanish label for "Verifying update" and a sentence for the second entry
that includes the "{}" token in the same place.
In `@src/lang/id.rs`:
- Line 762: The localization entry with the English string "Please wait while {}
verifies the update." uses a {} placeholder that doesn't match the runtime
lookup expecting {$appName}; update that string to use the {$appName} token
instead (i.e., change "{}" to "{$appName}") so the placeholder name aligns with
the lookup used by the code that resolves this localization key.
In `@src/lang/it.rs`:
- Around line 761-762: Two localization entries have empty translations so
Italian UI will show blank status text: replace the empty strings for the tuple
keys "Verifying update" and "Please wait while {} verifies the update." with
non-empty fallback text (e.g., the English phrases or temporary Italian
equivalents) in the it.rs mapping; update the second entry to keep the "{}"
placeholder intact so formatting (function/method that uses these keys)
continues to work correctly.
In `@src/lang/ja.rs`:
- Around line 761-762: Two new Japanese localization entries currently have
empty values: the tuple keys ("Verifying update", "") and ("Please wait while {}
verifies the update.", ""); update these by providing appropriate Japanese
translations for both labels in src/lang/ja.rs so the update dialog shows text
for the Japanese locale (replace the empty strings with translated text that
preserves the {} placeholder).
In `@src/lang/ko.rs`:
- Around line 761-762: Populate the two empty Korean translations for the
update-verification messages: replace the empty string for "Verifying update"
with an appropriate Korean phrase (e.g., "업데이트 확인 중") and replace the empty
string for "Please wait while {} verifies the update." with a formatted Korean
sentence that preserves the {} placeholder (e.g., "{}가(이) 업데이트를 확인하는 동안 기다려
주세요"). Update the tuples in src/lang/ko.rs where the keys "Verifying update" and
"Please wait while {} verifies the update." appear so the locale shows progress
text during verification.
In `@src/lang/kz.rs`:
- Around line 761-762: Provide non-empty Kazakh translations for the two
update-verification message keys in src/lang/kz.rs: replace the empty string
values for "Verifying update" and "Please wait while {} verifies the update."
with appropriate Kazakh text (e.g., concise translation for "Verifying update"
and a formatted string including "{}" placeholder preserved for "Please wait
while {} verifies the update.") so the status prompts display correctly during
update verification.
In `@src/lang/lt.rs`:
- Around line 761-762: Replace the empty Lithuanian placeholders for the status
messages: for the key "Verifying update" set an appropriate Lithuanian
translation (e.g., "Tikrinu atnaujinimą"), and for "Please wait while {}
verifies the update." set a Lithuanian sentence that preserves the placeholder
(e.g., "Prašome palaukti, kol {} patikrins atnaujinimą."). Update the tuple
entries that match those exact English strings so the update flow shows
user-facing Lithuanian text.
In `@src/lang/lv.rs`:
- Around line 761-762: The two localization entries in src/lang/lv.rs currently
have empty Latvian translations: the tuple with the English key "Verifying
update" and the tuple with "Please wait while {} verifies the update."; replace
those empty second-field strings with proper Latvian translations (i.e., fill
the second element of the two tuples) so the UI no longer shows blanks during
update verification—locate the tuples exactly by their English keys and update
their corresponding Latvian values.
In `@src/lang/tr.rs`:
- Around line 761-762: Provide Turkish translations for the two empty
localization entries: replace the empty values for the keys "Verifying update"
and "Please wait while {} verifies the update." in src/lang/tr.rs with
appropriate Turkish strings (e.g. "Güncelleme doğrulanıyor" and "Lütfen {}
güncellemenin doğrulanmasını bekleyin."). Update only the value parts of those
tuple entries so the keys remain unchanged.
In `@src/platform/windows.rs`:
- Around line 3603-3618: The function ensure_custom_client_staging_dir_is_safe
currently only inspects the leaf path; change it to validate every component of
the staging path (e.g. by canonicalizing or iterating parents and calling
std::fs::symlink_metadata for each path component) and call
is_update_file_attributes_trusted on each component's file_attributes() to
detect reparse/junctions anywhere in the path before returning Ok; update any
error messages in ensure_custom_client_staging_dir_is_safe to include which path
component failed so callers (and the staging/creation flow that uses
create_dir_all and fs::copy) cannot be tricked by an attacker-controlled
junction earlier in the path.
In `@src/updater.rs`:
- Around line 483-500: The function verify_existing_update_artifact currently
deletes the provided file on size or SHA mismatch; remove those
std::fs::remove_file(file_path)? calls so the helper only validates and returns
an error (use bail! on size mismatch and return Err from verify_file_sha256
failure) without deleting caller-owned files, and move/delete-on-mismatch logic
into the cache-owning path (ensure_verified_update_artifact) so that only the
updater's cache is cleaned up; reference verify_existing_update_artifact,
verify_file_sha256, and ensure_verified_update_artifact when making the change.
---
Duplicate comments:
In @.github/workflows/flutter-build.yml:
- Around line 826-886: The publish-signed-update-metadata job tries to download
macOS DMGs even when build-for-macOS omitted them due to missing macOS cert;
update the job's gating to require the macOS signing precondition used in
build-for-macOS (check env.MACOS_P12_BASE64 != '' or add a new output from
detect-update-metadata-signing like macos_signing_enabled) so the
publish-signed-update-metadata job only runs when macOS artifacts were actually
uploaded; modify the job named publish-signed-update-metadata's if: expression
to include this macOS signing check (or emit and use a
detect-update-metadata-signing output) to keep the release path consistent.
In `@src/lang/sq.rs`:
- Around line 761-762: Two Albanian localization entries currently have empty
values—specifically the tuples ("Verifying update", "") and ("Please wait while
{} verifies the update.", "") in src/lang/sq.rs—so replace the empty strings
with temporary English fallback text (e.g., "Verifying update" and "Please wait
while {} verifies the update.") until proper Albanian translations are provided;
update the corresponding tuples in the localization array or map so the UI shows
the fallback instead of blank text.
In `@src/lang/sr.rs`:
- Around line 761-762: The two Serbian localization tuples for the verification
flow ("Verifying update" and "Please wait while {} verifies the update.")
currently have empty values; replace those empty strings with appropriate
fallback text (e.g., English strings or a temporary Serbian fallback) so the
verification dialog doesn't render blank — update the value entries paired with
the keys "Verifying update" and "Please wait while {} verifies the update." in
the sr.rs localization list to non-empty fallback strings.
In `@src/lang/sv.rs`:
- Around line 761-762: Fill the empty fallback strings for the translation keys
"Verifying update" and "Please wait while {} verifies the update." by replacing
the "" values with Swedish translations (e.g. "Verifierar uppdatering" and
"Vänligen vänta medan {} verifierar uppdateringen.") so the tuple entries for
those keys return non-empty UI text.
In `@src/lang/ta.rs`:
- Around line 761-762: The two Tamil translation entries for the source strings
"Verifying update" and "Please wait while {} verifies the update." are empty;
replace the empty strings with a sensible fallback (e.g., the original English
text or a short Tamil placeholder) so the UI shows text during verification.
Locate the tuples in src/lang/ta.rs (the translation list containing ("Verifying
update", "") and ("Please wait while {} verifies the update.", "")) and update
the second element of each tuple to a non-empty fallback string.
In `@src/lang/th.rs`:
- Around line 761-762: The two new tuples ("Verifying update", "") and ("Please
wait while {} verifies the update.", "") in lang/th.rs contain empty
translations; replace the empty string values with appropriate fallback strings
(e.g., use the original English text or a short Thai placeholder) so
update-verification messages are not blank — update the entries for "Verifying
update" and "Please wait while {} verifies the update." with non-empty fallback
strings until proper Thai localizations are provided.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 84b1368b-7619-491d-bdfe-4cdc994dd89b
📒 Files selected for processing (69)
.github/workflows/flutter-build.yml.github/workflows/flutter-nightly.yml.github/workflows/flutter-tag.ymlflutter/lib/desktop/pages/desktop_home_page.dartflutter/lib/desktop/widgets/update_progress.dartlibs/hbb_commonres/generate_update_metadata.pyres/test_generate_update_metadata.pysrc/common.rssrc/core_main.rssrc/flutter_ffi.rssrc/hbbs_http/account.rssrc/hbbs_http/downloader.rssrc/hbbs_http/http_client.rssrc/hbbs_http/record_upload.rssrc/lang/ar.rssrc/lang/be.rssrc/lang/bg.rssrc/lang/ca.rssrc/lang/cn.rssrc/lang/cs.rssrc/lang/da.rssrc/lang/de.rssrc/lang/el.rssrc/lang/eo.rssrc/lang/es.rssrc/lang/et.rssrc/lang/eu.rssrc/lang/fa.rssrc/lang/fi.rssrc/lang/fr.rssrc/lang/ge.rssrc/lang/gu.rssrc/lang/he.rssrc/lang/hi.rssrc/lang/hr.rssrc/lang/hu.rssrc/lang/id.rssrc/lang/it.rssrc/lang/ja.rssrc/lang/ko.rssrc/lang/kz.rssrc/lang/lt.rssrc/lang/lv.rssrc/lang/ml.rssrc/lang/nb.rssrc/lang/nl.rssrc/lang/pl.rssrc/lang/pt_PT.rssrc/lang/ptbr.rssrc/lang/ro.rssrc/lang/ru.rssrc/lang/sc.rssrc/lang/sk.rssrc/lang/sl.rssrc/lang/sq.rssrc/lang/sr.rssrc/lang/sv.rssrc/lang/ta.rssrc/lang/template.rssrc/lang/th.rssrc/lang/tr.rssrc/lang/tw.rssrc/lang/uk.rssrc/lang/vi.rssrc/platform/macos.rssrc/platform/privileges_scripts/update.scptsrc/platform/windows.rssrc/updater.rs
eae0cf0 to
b0b8da9
Compare
b0b8da9 to
3c78f39
Compare
There was a problem hiding this comment.
Actionable comments posted: 15
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/common.rs (1)
1087-1121:⚠️ Potential issue | 🟠 Major | ⚡ Quick winReuse the strict URL-aware TLS probe for update checks.
Line 1091 locks this request to the last cached
TlsType, and Line 1102 only retries when there was no cache entry at all. If that cache is stale, update discovery can fail indefinitely even thoughcreate_http_client_async_with_url(..., true)already implements the strict re-probe/fallback path used elsewhere in this PR.💡 Minimal fix
- let proxy_conf = Config::get_socks(); - let tls_url = get_url_for_tls(&url, &proxy_conf); - let tls_type = get_cached_tls_type(tls_url); - let is_tls_not_cached = tls_type.is_none(); - let tls_type = tls_type.unwrap_or(TlsType::Rustls); - let client = create_http_client_async(tls_type, false); - let latest_release_response: ResultType<_> = match client.post(&url).json(&request).send().await - { - Ok(resp) => { - upsert_tls_cache(tls_url, tls_type, false); - Ok(resp) - } - Err(err) => { - if is_tls_not_cached && err.is_request() { - let tls_type = TlsType::NativeTls; - let client = create_http_client_async(tls_type, false); - match client.post(&url).json(&request).send().await { - Ok(resp) => { - upsert_tls_cache(tls_url, tls_type, false); - Ok(resp) - } - Err(err) => Err(err.into()), - } - } else { - Err(err.into()) - } - } - }; + let client = crate::hbbs_http::create_http_client_async_with_url(&url, true).await; + let latest_release_response: ResultType<_> = + match client.post(&url).json(&request).send().await { + Ok(resp) => Ok(resp), + Err(err) => Err(err.into()), + };🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/common.rs` around lines 1087 - 1121, The current code uses create_http_client_async(tls_type, false) and only retries with NativeTls when there was no cached TlsType, which lets stale cache block update checks; replace the client creation logic for the update check to call create_http_client_async_with_url(&url, tls_type, true) (i.e., the strict URL-aware probe/fallback path) instead of create_http_client_async(...) so the probe will re-check/fallback even when a cached tls_type exists; keep upsert_tls_cache(tls_url, tls_type, false) as before after a successful response so the cache is updated by the probe.
♻️ Duplicate comments (17)
src/lang/hr.rs (1)
762-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winFix placeholder token mismatch in the key string.
{}should be{$appName}for runtime key compatibility.Suggested fix
- ("Please wait while {} verifies the update.", ""), + ("Please wait while {$appName} verifies the update.", ""),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/hr.rs` at line 762, The translation entry tuple containing the string "Please wait while {} verifies the update." uses the wrong placeholder token; update that string to use the runtime token {$appName} instead of {} so it matches expected runtime interpolation (locate the entry in src/lang/hr.rs and replace "{}" with "{$appName}" in the tuple for the verification message).src/lang/hu.rs (1)
762-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winUse
{$appName}in this localization key.The
{}token can break expected lookup/substitution behavior.Suggested fix
- ("Please wait while {} verifies the update.", ""), + ("Please wait while {$appName} verifies the update.", ""),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/hu.rs` at line 762, Replace the positional "{}" placeholder in the Hungarian localization entry with the named placeholder "{$appName}" so it matches the app's lookup/substitution conventions; locate the tuple entry in src/lang/hu.rs (the line containing ("Please wait while {} verifies the update.", "")) and update the source string to use "{$appName}" and ensure any corresponding translation string uses the same "{$appName}" token.src/lang/id.rs (1)
762-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winUpdate placeholder token to the runtime form.
Please use
{$appName}instead of{}in this key.Suggested fix
- ("Please wait while {} verifies the update.", ""), + ("Please wait while {$appName} verifies the update.", ""),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/id.rs` at line 762, Replace the positional placeholder "{}" with the runtime token "{$appName}" in the localization entry ("Please wait while {} verifies the update.", "") in src/lang/id.rs so the runtime can substitute the app name; update the first string to "Please wait while {$appName} verifies the update." ensuring the key uses the {$appName} token expected by the runtime.src/lang/gu.rs (1)
762-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winUse the runtime placeholder token in this localization key.
This key should use
{$appName}instead of{}to match runtime lookup/substitution.Suggested fix
- ("Please wait while {} verifies the update.", ""), + ("Please wait while {$appName} verifies the update.", ""),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/gu.rs` at line 762, The localization entry in src/lang/gu.rs currently uses a positional placeholder "{}" ("Please wait while {} verifies the update.") which must be replaced with the runtime token "{$appName}"; update that tuple string so it reads "Please wait while {$appName} verifies the update." to match the runtime lookup/substitution used elsewhere (search for this string or the localization map entry to locate and update).src/lang/he.rs (1)
762-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winReplace
{}with the expected runtime token in the key.Use
{$appName}so this key matches runtime localization lookup.Suggested fix
- ("Please wait while {} verifies the update.", ""), + ("Please wait while {$appName} verifies the update.", ""),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/he.rs` at line 762, Update the localization key string that currently uses a positional token ("Please wait while {} verifies the update.") to use the runtime token syntax ("{$appName}") so the lookup matches the runtime localization lookup; locate the tuple entry in src/lang/he.rs (the string literal used as the map key) and replace {} with {$appName}, leaving the translation value intact.src/lang/hi.rs (1)
762-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winNormalize placeholder token in the localization key.
Use
{$appName}instead of{}to align with runtime key format.Suggested fix
- ("Please wait while {} verifies the update.", ""), + ("Please wait while {$appName} verifies the update.", ""),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/hi.rs` at line 762, The localization key tuple ("Please wait while {} verifies the update.", "") uses a bare {} placeholder; update the key to use the normalized token by replacing {} with {$appName} so it becomes ("Please wait while {$appName} verifies the update.", "") to match the runtime placeholder format used by the localization system.src/lang/kz.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winUse non-empty text for the new Kazakh update-verification keys.
Both values are empty, so verification prompts can appear blank. Please provide translations or an English fallback, preserving
{}.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/kz.rs` around lines 761 - 762, The two Kazakh localization entries with keys "Verifying update" and "Please wait while {} verifies the update." currently have empty translations; replace the empty strings with proper Kazakh translations or an English fallback that preserves the placeholder `{}` (e.g., a non-empty string for "Verifying update" and a sentence retaining `{}` for the second key) so verification prompts are not blank.src/lang/ko.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winPopulate the Korean verification messages instead of empty placeholders.
Leaving both translations empty will render blank status text during update verification. Keep
{}unchanged in the second entry.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/ko.rs` around lines 761 - 762, Replace the two empty Korean translation strings for the keys "Verifying update" and "Please wait while {} verifies the update." in src/lang/ko.rs with proper Korean text (e.g., "업데이트 확인 중" for the first and "업데이트를 확인하는 중입니다: {}" or similar for the second), making sure to keep the "{}" placeholder exactly as-is in the second string so interpolation still works.src/lang/ja.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winDo not leave new Japanese verification strings empty.
Empty values here cause blank labels in the update flow. Please populate both entries and preserve
{}in the second string.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/ja.rs` around lines 761 - 762, The two Japanese localization entries for "Verifying update" and "Please wait while {} verifies the update." are empty; replace the empty strings with appropriate Japanese translations while preserving the placeholder {} in the second string (e.g., "更新を検証中" for the first and "{}が更新を検証しています。しばらくお待ちください。" for the second) so the update flow shows proper labels; update the tuple entries for the keys "Verifying update" and "Please wait while {} verifies the update." in src/lang/ja.rs accordingly.src/lang/lv.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winReplace empty Latvian values for verification status messages.
Both entries are empty and can render as blank in the update UI. Please provide non-empty localized text while preserving
{}.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/lv.rs` around lines 761 - 762, The two Latvian localization entries for the verification messages currently have empty values; replace the empty strings for the keys "Verifying update" and "Please wait while {} verifies the update." in src/lang/lv.rs with proper Latvian translations (e.g., "Tiek pārbaudīts atjauninājums" and "Lūdzu gaidiet, kamēr {} pārbauda atjauninājumu."), making sure to preserve the placeholder {} exactly as in the original strings and keep punctuation/spacing appropriate for UI display.src/lang/lt.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winFill in the Lithuanian verification strings.
Empty values here cause blank user-facing status text during update verification. Please set non-empty values and keep
{}in the formatted sentence.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/lt.rs` around lines 761 - 762, The two translation entries for "Verifying update" and "Please wait while {} verifies the update." currently have empty Lithuanian strings; replace the second element of each tuple with proper Lithuanian translations (e.g., "Tikrinu atnaujinimą" for "Verifying update" and "Prašome palaukti, kol {} tikrins atnaujinimą." for the formatted sentence), ensuring you keep the {} placeholder exactly as-is in the second string so formatting still works.src/lang/it.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAvoid empty translations for update verification labels.
These values are empty, so the Italian UI can render blank status text during verification. Please provide non-empty strings (at minimum, English fallback) and keep
{}intact.Suggested patch
- ("Verifying update", ""), - ("Please wait while {} verifies the update.", ""), + ("Verifying update", "Verifying update"), + ("Please wait while {} verifies the update.", "Please wait while {} verifies the update."),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/it.rs` around lines 761 - 762, The two Italian translation entries ("Verifying update", "") and ("Please wait while {} verifies the update.", "") are empty; replace the empty strings with non-empty translations (or at minimum the English fallback) and preserve the placeholder {} exactly as-is. Update the tuple values in src/lang/it.rs for the keys "Verifying update" and "Please wait while {} verifies the update." so the Italian UI displays a proper message (e.g., "Verifica aggiornamento" and "Attendere mentre {} verifica l'aggiornamento." or the English fallback), ensuring no placeholders are altered or removed.src/lang/uk.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winFill Ukrainian update-verification translations.
Line 761 and Line 762 are empty, so users won’t see verification progress text.
Suggested patch
- ("Verifying update", ""), - ("Please wait while {} verifies the update.", ""), + ("Verifying update", "Перевірка оновлення"), + ("Please wait while {} verifies the update.", "Зачекайте, будь ласка, поки {} перевіряє оновлення."),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/uk.rs` around lines 761 - 762, Fill in the missing Ukrainian translations for the two translation entries by replacing the empty strings for the keys ("Verifying update", "") and ("Please wait while {} verifies the update.", "") with appropriate Ukrainian text (e.g., "Перевірка оновлення" and "Будь ласка, зачекайте, поки {} перевіряє оновлення.") so the verification progress messages display correctly in uk.rs.src/lang/tr.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winFill missing Turkish update-verification translations.
Line 761 and Line 762 are empty, so verification UI text will be blank.
Suggested patch
- ("Verifying update", ""), - ("Please wait while {} verifies the update.", ""), + ("Verifying update", "Güncelleme doğrulanıyor"), + ("Please wait while {} verifies the update.", "Lütfen {} güncellemeyi doğrularken bekleyin."),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/tr.rs` around lines 761 - 762, The two translation tuples ("Verifying update", "") and ("Please wait while {} verifies the update.", "") in src/lang/tr.rs are empty; replace the empty strings with proper Turkish translations (e.g., "Güncelleme doğrulanıyor" and "Lütfen {} güncellemenin doğrulanmasını bekleyin." or equivalent) so the update verification UI shows correct Turkish text; update those exact tuple entries in the file.src/lang/tw.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winProvide Traditional Chinese strings for verification status.
Line 761 and Line 762 currently map to empty strings and will display blank UI text.
Suggested patch
- ("Verifying update", ""), - ("Please wait while {} verifies the update.", ""), + ("Verifying update", "正在驗證更新"), + ("Please wait while {} verifies the update.", "請稍候,{} 正在驗證更新。"),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/tw.rs` around lines 761 - 762, The two translation entries for the keys "Verifying update" and "Please wait while {} verifies the update." in src/lang/tw.rs are empty; replace the empty strings with appropriate Traditional Chinese translations (e.g., "正在驗證更新" for "Verifying update" and "請稍候,{} 正在驗證更新。" for the templated sentence) so the UI no longer shows blank text; update the tuple values that correspond to those English keys in the file.src/lang/vi.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAdd Vietnamese translations for update verification strings.
Line 761 and Line 762 are empty, which results in blank UI messages during verification.
Suggested patch
- ("Verifying update", ""), - ("Please wait while {} verifies the update.", ""), + ("Verifying update", "Đang xác minh bản cập nhật"), + ("Please wait while {} verifies the update.", "Vui lòng chờ trong khi {} xác minh bản cập nhật."),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/vi.rs` around lines 761 - 762, Replace the two empty Vietnamese translation entries for the update verification messages: find the tuple ("Verifying update", "") and set its translation to a suitable Vietnamese string (e.g., "Đang xác minh bản cập nhật"), and find ("Please wait while {} verifies the update.", "") and set its translation to a Vietnamese sentence with the same placeholder (e.g., "Vui lòng chờ trong khi {} xác minh bản cập nhật"); ensure you preserve the {} placeholder exactly and update the tuples in src/lang/vi.rs accordingly.src/flutter_ffi.rs (1)
2875-2881:⚠️ Potential issue | 🟠 Major | 🏗️ Heavy liftDon't discard the verified artifact context at the FFI boundary.
Returning only
artifact.urlhere forces Lines 2971-2995 and Lines 3002-3011 to callverified_update_artifact_for_download_url(...)again. A user can therefore finish the download and still fail to install when offline or rate-limited, because the original signed metadata is no longer available. Pass an opaque verified-artifact payload through Flutter, or persist the signed sidecars next to the download and consume those during"update-me".🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/flutter_ffi.rs` around lines 2875 - 2881, The branch that handles keys starting with "verified-download-url-" currently returns only artifact.url from verified_update_artifact_for_release_page_url, discarding the signed-artifact context; instead modify the FFI boundary so the opaque verified-artifact payload (or the signed sidecar metadata) is preserved and passed through Flutter or persisted alongside the downloaded file and consumed by the "update-me" path; specifically, change the behavior in the key.starts_with("verified-download-url-") branch and verified_update_artifact_for_release_page_url to return/serialize the full verified artifact payload (or write the signed sidecars next to the download) and update the code that later calls verified_update_artifact_for_download_url and the "update-me" handler to read that payload rather than recomputing it.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@res/generate_update_metadata.py`:
- Around line 17-18: The hardcoded GITHUB_RELEASE_PREFIX (currently
"https://github.com/rustdesk/rustdesk/releases/download") causes generated
metadata to point at the wrong repo; change the code that builds release-asset
URLs (referenced around GITHUB_RELEASE_PREFIX and the URL-construction logic in
the functions handling metadata lines ~47-72) to accept a repository identifier
parameter (e.g., repo or upstream_repo) and use that when composing the release
download base instead of the hardcoded "rustdesk/rustdesk"; ensure the parameter
is passed in from the workflow or a top-level constant so fragment/verify
continue to work for different repositories.
In `@res/test_generate_update_metadata.py`:
- Around line 159-174: Add a positive end-to-end assertion that the happy path
verification succeeds before the tamper and missing-artifact checks: in
test_verify_fails_after_artifact_tamper_or_missing_local_artifact (after calling
make_fragment() and sign_fragments()) call verify_release(metadata, signature,
[artifact], check=False) and assert its returncode equals 0 to ensure the
verifier actually accepts valid inputs; keep the subsequent tamper and
missing-artifact assertions unchanged.
In `@src/lang/ar.rs`:
- Around line 761-762: Replace the empty localization values for the
verification-status entries in src/lang/ar.rs: update the tuple for "Verifying
update" and the tuple for "Please wait while {} verifies the update." to include
proper Arabic translations (or an English fallback) while preserving the {}
placeholder exactly; ensure the translated strings correspond to the source keys
and remove the empty "" values so the UI shows the message during update
verification.
In `@src/lang/be.rs`:
- Around line 761-762: Two locale entries currently have empty translations: the
tuple with key "Verifying update" and the tuple with key "Please wait while {}
verifies the update."; replace the empty strings with proper Belarusian
translations and keep the placeholder `{}` exactly as-is in the second string so
formatting continues to work (update the values for the tuples in src/lang/be.rs
corresponding to those keys).
In `@src/lang/bg.rs`:
- Around line 761-762: The two Bulgarian translation entries for the UI strings
("Verifying update", "") and ("Please wait while {} verifies the update.", "")
are empty; replace the empty second elements with appropriate Bulgarian
translations while preserving the `{}` placeholder (for example: "Проверка на
актуализацията" and "Моля, изчакайте, докато {} проверява актуализацията.").
Ensure the translations are non-empty, keep the exact `{}` token intact, and
match the existing tuple format in src/lang/bg.rs.
In `@src/lang/ca.rs`:
- Around line 761-762: Replace the two empty Catalan translation strings for the
keys ("Verifying update", "") and ("Please wait while {} verifies the update.",
"") with proper non-empty Catalan translations, preserving the {} placeholder
for interpolation (e.g., "Verificant l'actualització" and "Si us plau, espereu
mentre {} verifica l'actualització."). Ensure the second string keeps the {}
exactly where the verifier name will be inserted.
In `@src/lang/ml.rs`:
- Around line 761-762: Two localization entries for the keys "Verifying update"
and "Please wait while {} verifies the update." are empty; replace their empty
Malayalam values with proper translations: set "Verifying update" -> "അപ്ഡേറ്റ്
പരിശോധിക്കുന്നു" and set "Please wait while {} verifies the update." -> "{}
അപ്ഡേറ്റ് പരിശോദിക്കുമ്പോൾ ദಯവായി കാത്തിരിക്കുക." Update the tuple values in
src/lang/ml.rs for those exact keys ("Verifying update" and "Please wait while
{} verifies the update.") so the UI shows the Malayalam status text during
update verification.
In `@src/lang/nb.rs`:
- Around line 761-762: Replace the empty Norwegian translations for the two
tuple entries identified by the source strings "Verifying update" and "Please
wait while {} verifies the update." with proper Norwegian text (e.g.
"Verifiserer oppdatering" and "Vennligst vent mens {} verifiserer
oppdateringen."). Update the tuple values in the same entries so they are
non-empty and correctly escaped/formed to match the surrounding localization
tuples (preserve the {} placeholder in the second string).
In `@src/lang/nl.rs`:
- Around line 761-762: The two Dutch translation entries for the update
verification messages are empty: replace the tuple values for ("Verifying
update", "") and ("Please wait while {} verifies the update.", "") with proper
Dutch translations (e.g., "Update wordt geverifieerd" or "Bezig met het
verifiëren van de update" and "Wacht even terwijl {} de update verifieert.") so
the update status text is shown correctly in nl translations.
In `@src/lang/pl.rs`:
- Around line 761-762: The two translation entries for the keys "Verifying
update" and "Please wait while {} verifies the update." are empty; add Polish
translations by replacing the empty values in the translation tuple list in
src/lang/pl.rs for those exact keys (preserve the {} placeholder). For example,
set "Verifying update" -> "Weryfikowanie aktualizacji" and "Please wait while {}
verifies the update." -> "Proszę czekać, podczas gdy {} weryfikuje
aktualizację." ensuring the placeholder and punctuation remain unchanged.
In `@src/lang/pt_PT.rs`:
- Around line 761-762: Replace the empty Portuguese translations for the update
verification messages in src/lang/pt_PT.rs: set the tuple for "Verifying update"
to "A verificar a actualização" and the tuple for "Please wait while {} verifies
the update." to "Por favor, aguarde enquanto {} verifica a actualização." so the
two entries read ("Verifying update", "A verificar a actualização") and ("Please
wait while {} verifies the update.", "Por favor, aguarde enquanto {} verifica a
actualização.").
In `@src/platform/macos.rs`:
- Around line 1055-1062: The TOCTOU exists because update_from_verified_dmg
verifies the temp DMG via verify_dmg_file_sha256 on a user-writable temp file
(created by copy_dmg_to_update_temp_file) but then passes only the temp path
into update_from_mounted_dmg which runs privileged hdiutil attach and
update_me_from_app_dir; to fix, either (a) perform a fresh SHA256 verification
inside the privileged path before mounting (move the verify_dmg_file_sha256 call
into update_from_mounted_dmg / the privileged install flow so the file is hashed
under the same privilege boundary), or (b) atomically stage the already-verified
DMG into a root-owned, non-writable location and mount it read-only (after
copy_dmg_to_update_temp_file succeeds, chown/chmod and move the temp to a
root-owned secure path, then call update_from_mounted_dmg on that path and
ensure hdiutil attach uses read-only flags), and ensure update_me_from_app_dir
does not trust an externally writable path.
In `@src/platform/windows.rs`:
- Around line 3615-3638: The staging-path reparse check is only applied before
writing; update prepare_custom_client_update to call
ensure_custom_client_staging_dir_is_safe(&custom_client_staging_dir) (or
equivalent) before performing the read-side checks (e.g. before
custom_txt_path.exists() / std::fs::symlink_metadata(custom_txt_path)); this
ensures the parent/junction components of custom_client_staging_dir are
validated and prevents a junctioned RustDeskCustomClientStaging from redirecting
reads to attacker-controlled locations. Make sure to propagate or handle the
Result/anyhow error from ensure_custom_client_staging_dir_is_safe in
prepare_custom_client_update.
- Around line 3675-3682: The current .exe branch in update_to_verified drops the
VerifiedUpdateFile before launching via run_uac(update_file.path_str()?,
"--update"), creating a TOCTOU risk; instead, use the verified file handle
(VerifiedUpdateFile) to atomically copy the verified bytes to an admin-only,
non-user-writable location (for example ProgramData or another secured temp
path) while the handle is still held, flush and set appropriate ACLs so an
unprivileged user cannot replace it, then call run_uac with that secured path;
alternatively, embed the expected SHA256 into the elevated invocation so the
elevated process re-verifies before executing (symbols to locate:
update_to_verified, VerifiedUpdateFile, verified_update_file_path, run_uac,
ShellExecuteW).
In `@src/updater.rs`:
- Around line 500-546: The code calls create_http_client_with_url(download_url,
true) (which probes the network) before checking cached file size/SHA256,
preventing reuse when offline; move the create_http_client_with_url call so it
only runs after determining is_file_exists is false (i.e., after the existing
file size and verify_file_sha256 checks), and then use that client for the
download and response handling in ensure_verified_update_artifact; keep
verify_file_sha256 and write_verified_update_artifact usage unchanged and only
instantiate the HTTP client when you actually need to perform the download.
---
Outside diff comments:
In `@src/common.rs`:
- Around line 1087-1121: The current code uses
create_http_client_async(tls_type, false) and only retries with NativeTls when
there was no cached TlsType, which lets stale cache block update checks; replace
the client creation logic for the update check to call
create_http_client_async_with_url(&url, tls_type, true) (i.e., the strict
URL-aware probe/fallback path) instead of create_http_client_async(...) so the
probe will re-check/fallback even when a cached tls_type exists; keep
upsert_tls_cache(tls_url, tls_type, false) as before after a successful response
so the cache is updated by the probe.
---
Duplicate comments:
In `@src/flutter_ffi.rs`:
- Around line 2875-2881: The branch that handles keys starting with
"verified-download-url-" currently returns only artifact.url from
verified_update_artifact_for_release_page_url, discarding the signed-artifact
context; instead modify the FFI boundary so the opaque verified-artifact payload
(or the signed sidecar metadata) is preserved and passed through Flutter or
persisted alongside the downloaded file and consumed by the "update-me" path;
specifically, change the behavior in the
key.starts_with("verified-download-url-") branch and
verified_update_artifact_for_release_page_url to return/serialize the full
verified artifact payload (or write the signed sidecars next to the download)
and update the code that later calls verified_update_artifact_for_download_url
and the "update-me" handler to read that payload rather than recomputing it.
In `@src/lang/gu.rs`:
- Line 762: The localization entry in src/lang/gu.rs currently uses a positional
placeholder "{}" ("Please wait while {} verifies the update.") which must be
replaced with the runtime token "{$appName}"; update that tuple string so it
reads "Please wait while {$appName} verifies the update." to match the runtime
lookup/substitution used elsewhere (search for this string or the localization
map entry to locate and update).
In `@src/lang/he.rs`:
- Line 762: Update the localization key string that currently uses a positional
token ("Please wait while {} verifies the update.") to use the runtime token
syntax ("{$appName}") so the lookup matches the runtime localization lookup;
locate the tuple entry in src/lang/he.rs (the string literal used as the map
key) and replace {} with {$appName}, leaving the translation value intact.
In `@src/lang/hi.rs`:
- Line 762: The localization key tuple ("Please wait while {} verifies the
update.", "") uses a bare {} placeholder; update the key to use the normalized
token by replacing {} with {$appName} so it becomes ("Please wait while
{$appName} verifies the update.", "") to match the runtime placeholder format
used by the localization system.
In `@src/lang/hr.rs`:
- Line 762: The translation entry tuple containing the string "Please wait while
{} verifies the update." uses the wrong placeholder token; update that string to
use the runtime token {$appName} instead of {} so it matches expected runtime
interpolation (locate the entry in src/lang/hr.rs and replace "{}" with
"{$appName}" in the tuple for the verification message).
In `@src/lang/hu.rs`:
- Line 762: Replace the positional "{}" placeholder in the Hungarian
localization entry with the named placeholder "{$appName}" so it matches the
app's lookup/substitution conventions; locate the tuple entry in src/lang/hu.rs
(the line containing ("Please wait while {} verifies the update.", "")) and
update the source string to use "{$appName}" and ensure any corresponding
translation string uses the same "{$appName}" token.
In `@src/lang/id.rs`:
- Line 762: Replace the positional placeholder "{}" with the runtime token
"{$appName}" in the localization entry ("Please wait while {} verifies the
update.", "") in src/lang/id.rs so the runtime can substitute the app name;
update the first string to "Please wait while {$appName} verifies the update."
ensuring the key uses the {$appName} token expected by the runtime.
In `@src/lang/it.rs`:
- Around line 761-762: The two Italian translation entries ("Verifying update",
"") and ("Please wait while {} verifies the update.", "") are empty; replace the
empty strings with non-empty translations (or at minimum the English fallback)
and preserve the placeholder {} exactly as-is. Update the tuple values in
src/lang/it.rs for the keys "Verifying update" and "Please wait while {}
verifies the update." so the Italian UI displays a proper message (e.g.,
"Verifica aggiornamento" and "Attendere mentre {} verifica l'aggiornamento." or
the English fallback), ensuring no placeholders are altered or removed.
In `@src/lang/ja.rs`:
- Around line 761-762: The two Japanese localization entries for "Verifying
update" and "Please wait while {} verifies the update." are empty; replace the
empty strings with appropriate Japanese translations while preserving the
placeholder {} in the second string (e.g., "更新を検証中" for the first and
"{}が更新を検証しています。しばらくお待ちください。" for the second) so the update flow shows proper
labels; update the tuple entries for the keys "Verifying update" and "Please
wait while {} verifies the update." in src/lang/ja.rs accordingly.
In `@src/lang/ko.rs`:
- Around line 761-762: Replace the two empty Korean translation strings for the
keys "Verifying update" and "Please wait while {} verifies the update." in
src/lang/ko.rs with proper Korean text (e.g., "업데이트 확인 중" for the first and
"업데이트를 확인하는 중입니다: {}" or similar for the second), making sure to keep the "{}"
placeholder exactly as-is in the second string so interpolation still works.
In `@src/lang/kz.rs`:
- Around line 761-762: The two Kazakh localization entries with keys "Verifying
update" and "Please wait while {} verifies the update." currently have empty
translations; replace the empty strings with proper Kazakh translations or an
English fallback that preserves the placeholder `{}` (e.g., a non-empty string
for "Verifying update" and a sentence retaining `{}` for the second key) so
verification prompts are not blank.
In `@src/lang/lt.rs`:
- Around line 761-762: The two translation entries for "Verifying update" and
"Please wait while {} verifies the update." currently have empty Lithuanian
strings; replace the second element of each tuple with proper Lithuanian
translations (e.g., "Tikrinu atnaujinimą" for "Verifying update" and "Prašome
palaukti, kol {} tikrins atnaujinimą." for the formatted sentence), ensuring you
keep the {} placeholder exactly as-is in the second string so formatting still
works.
In `@src/lang/lv.rs`:
- Around line 761-762: The two Latvian localization entries for the verification
messages currently have empty values; replace the empty strings for the keys
"Verifying update" and "Please wait while {} verifies the update." in
src/lang/lv.rs with proper Latvian translations (e.g., "Tiek pārbaudīts
atjauninājums" and "Lūdzu gaidiet, kamēr {} pārbauda atjauninājumu."), making
sure to preserve the placeholder {} exactly as in the original strings and keep
punctuation/spacing appropriate for UI display.
In `@src/lang/tr.rs`:
- Around line 761-762: The two translation tuples ("Verifying update", "") and
("Please wait while {} verifies the update.", "") in src/lang/tr.rs are empty;
replace the empty strings with proper Turkish translations (e.g., "Güncelleme
doğrulanıyor" and "Lütfen {} güncellemenin doğrulanmasını bekleyin." or
equivalent) so the update verification UI shows correct Turkish text; update
those exact tuple entries in the file.
In `@src/lang/tw.rs`:
- Around line 761-762: The two translation entries for the keys "Verifying
update" and "Please wait while {} verifies the update." in src/lang/tw.rs are
empty; replace the empty strings with appropriate Traditional Chinese
translations (e.g., "正在驗證更新" for "Verifying update" and "請稍候,{} 正在驗證更新。" for the
templated sentence) so the UI no longer shows blank text; update the tuple
values that correspond to those English keys in the file.
In `@src/lang/uk.rs`:
- Around line 761-762: Fill in the missing Ukrainian translations for the two
translation entries by replacing the empty strings for the keys ("Verifying
update", "") and ("Please wait while {} verifies the update.", "") with
appropriate Ukrainian text (e.g., "Перевірка оновлення" and "Будь ласка,
зачекайте, поки {} перевіряє оновлення.") so the verification progress messages
display correctly in uk.rs.
In `@src/lang/vi.rs`:
- Around line 761-762: Replace the two empty Vietnamese translation entries for
the update verification messages: find the tuple ("Verifying update", "") and
set its translation to a suitable Vietnamese string (e.g., "Đang xác minh bản
cập nhật"), and find ("Please wait while {} verifies the update.", "") and set
its translation to a Vietnamese sentence with the same placeholder (e.g., "Vui
lòng chờ trong khi {} xác minh bản cập nhật"); ensure you preserve the {}
placeholder exactly and update the tuples in src/lang/vi.rs accordingly.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 8b2c97e2-750b-4f47-94e4-84ee62518a58
📒 Files selected for processing (69)
.github/workflows/flutter-build.yml.github/workflows/flutter-nightly.yml.github/workflows/flutter-tag.ymlflutter/lib/desktop/pages/desktop_home_page.dartflutter/lib/desktop/widgets/update_progress.dartlibs/hbb_commonres/generate_update_metadata.pyres/test_generate_update_metadata.pysrc/common.rssrc/core_main.rssrc/flutter_ffi.rssrc/hbbs_http/account.rssrc/hbbs_http/downloader.rssrc/hbbs_http/http_client.rssrc/hbbs_http/record_upload.rssrc/lang/ar.rssrc/lang/be.rssrc/lang/bg.rssrc/lang/ca.rssrc/lang/cn.rssrc/lang/cs.rssrc/lang/da.rssrc/lang/de.rssrc/lang/el.rssrc/lang/eo.rssrc/lang/es.rssrc/lang/et.rssrc/lang/eu.rssrc/lang/fa.rssrc/lang/fi.rssrc/lang/fr.rssrc/lang/ge.rssrc/lang/gu.rssrc/lang/he.rssrc/lang/hi.rssrc/lang/hr.rssrc/lang/hu.rssrc/lang/id.rssrc/lang/it.rssrc/lang/ja.rssrc/lang/ko.rssrc/lang/kz.rssrc/lang/lt.rssrc/lang/lv.rssrc/lang/ml.rssrc/lang/nb.rssrc/lang/nl.rssrc/lang/pl.rssrc/lang/pt_PT.rssrc/lang/ptbr.rssrc/lang/ro.rssrc/lang/ru.rssrc/lang/sc.rssrc/lang/sk.rssrc/lang/sl.rssrc/lang/sq.rssrc/lang/sr.rssrc/lang/sv.rssrc/lang/ta.rssrc/lang/template.rssrc/lang/th.rssrc/lang/tr.rssrc/lang/tw.rssrc/lang/uk.rssrc/lang/vi.rssrc/platform/macos.rssrc/platform/privileges_scripts/update.scptsrc/platform/windows.rssrc/updater.rs
4512ffb to
6d8652f
Compare
6d8652f to
0d42621
Compare
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/platform/privileges_scripts/update.scpt (1)
19-31:⚠️ Potential issue | 🟠 Major | 🏗️ Heavy liftKeep the rollback copy until the launchd update finishes.
install_staged_bundledeletes$old_bundle, and only after that dowrite_daemon_plist,write_agent_plist,load_service, andload_agentrun underset -e. If any of those later steps fails, the script aborts after the previous app is gone and after the service/agent were unloaded, leaving a partially updated install with no restored daemon. Delay therm -rf "$old_bundle"until the plist/load steps succeed, or make the EXIT path restore$old_bundleand the previous launchd state on failure.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/platform/privileges_scripts/update.scpt` around lines 19 - 31, The script currently removes the previous app bundle inside install_staged_bundle before writing/loading plists (write_daemon_plist, write_agent_plist, load_service, load_agent), which can leave the system without a working daemon if any later step fails; to fix, stop deleting $old_bundle in install_staged_bundle and instead perform the rm -rf "$old_bundle" only after load_service and load_agent succeed (i.e., append the deletion after load_agent in the sh command), or alternatively enhance the cleanup_verified EXIT trap to detect failure and restore $old_bundle and the previous launchd state (recreate previous plist files and run launchctl bootstrap/load for the old agent/daemon) so the previous bundle and services are restored on error.src/common.rs (1)
2316-2390:⚠️ Potential issue | 🟠 Major | ⚡ Quick winDon't overload the return value with branding state.
read_custom_client()now returnsfalsefor any valid, signed config whoseapp-nameis"RustDesk"or omitted. The downstream caller insrc/platform/windows.rsLine 2089 stores this asis_valid_custom_client, so those payloads will be treated as invalid even though decode/signature/JSON validation succeeded. Keep this return value as “config is valid” (or switch to aResult/enum) and let callers querycrate::is_custom_client()separately for branding state. Please add a regression for a signed config that keeps the default app name.Suggested direction
pub fn read_custom_client(config: &str) -> bool { let Ok(data) = decode64(config) else { log::error!("Failed to decode custom client config"); return false; @@ - let mut is_custom_client = false; if let Some(app_name) = data.remove("app-name") { if let Some(app_name) = app_name.as_str() { - is_custom_client = app_name != "RustDesk"; *config::APP_NAME.write().unwrap() = app_name.to_owned(); } } @@ - is_custom_client + true }Then update the downstream caller to use this as a validity check only, and call
crate::is_custom_client()if it also needs branding state.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/common.rs` around lines 2316 - 2390, read_custom_client currently returns is_custom_client (branding) which causes valid signed configs with default/“RustDesk” app-name to be treated as invalid; change the function to return true when decoding/signature/JSON parsing succeed (i.e., treat the return value as “config valid”), and stop using the return value to convey branding. Concretely: in read_custom_client(...) remove using is_custom_client as the function return and instead return true at the end whenever processing completed successfully (keep setting config::APP_NAME and crate::is_custom_client() state as before); leave is_custom_client/local variable only to update branding state via whatever crate::is_custom_client() mechanism exists. Then update the downstream caller that currently assigns read_custom_client(...) into is_valid_custom_client to treat that return as validity-only and call crate::is_custom_client() separately when it needs branding info. Also add a regression test that verifies a signed config with the default app-name parses as valid.
♻️ Duplicate comments (12)
.github/workflows/flutter-tag.yml (1)
17-19:⚠️ Potential issue | 🟠 Major | ⚡ Quick winDon't force the signed-metadata path for every tag build.
publish-signed-update-metadataonly checks this caller input, but the producing jobs upload those artifacts only when platform signing is actually available. With this hardcodedtrue, a tag build that lacks one of those signing prerequisites skips the producer upload and then fails later when the publish job downloads missing artifacts.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/flutter-tag.yml around lines 17 - 19, The workflow currently forces publish/update metadata for every tag build by setting publish-update-metadata (and implicitly the signed-metadata path) to true; change this to not be hardcoded—make publish-update-metadata (or the specific publish-signed-update-metadata input) conditional or default to false and only set it true when platform signing is available (e.g., guard it with a conditional expression that checks an env flag like SIGNING_AVAILABLE, a job output indicating signing artifacts were produced, or the presence of the signing jobs), so the producer upload jobs (upload-artifact / upload-tag) run when appropriate and the publish job won’t fail downloading missing artifacts..github/workflows/flutter-build.yml (2)
891-901:⚠️ Potential issue | 🟠 Major | ⚡ Quick winThe signed-metadata pipeline is still hardwired to
rustdesk/rustdesk..github/workflows/flutter-build.ymlgenerates fragment URLs for upstream, andres/generate_update_metadata.pyonly accepts/verifies that same upstream release prefix. That shared root cause means the workflow and verifier stay internally consistent while still producing invalid metadata for releases published from any other repository.res/test_generate_update_metadata.pyalso bakes in the same assumption, so the test suite will not catch this regression until the fixture is updated too.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/flutter-build.yml around lines 891 - 901, The workflow hardcodes release URLs to rustdesk/rustdesk which causes generated fragments and the verifier to be invalid for other repositories; update the job that runs the fragment generation in .github/workflows/flutter-build.yml to derive the repo from an env var (e.g., GITHUB_REPOSITORY or a new REPO env) and pass that repository into res/generate_update_metadata.py (add a --repository or --upstream-repo flag), then update res/generate_update_metadata.py to accept/validate that repository instead of assuming rustdesk/rustdesk and make res/test_generate_update_metadata.py use fixtures or a parameterized repo value matching the new flag so the tests catch non-rustdesk repos; ensure all places referencing the hardcoded string are replaced (workflow generation lines, generate_update_metadata.py parser/validator, and test file).
837-841:⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift
cargo checkstill doesn't validate the Rust-side metadata verifier.This job proves the Python generator/verifier works, and that
hbb_commoncompiles, but it never exercises the Rust verifier against the generatedrustdesk-update.json. A schema or validation drift here can still publish metadata that CI accepts and the client rejects at runtime.Based on the review stack context, the runtime update flow consumes the Rust-side verifier path, so compiling
hbb_commonhere is not equivalent to validating the signed metadata contract.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/flutter-build.yml around lines 837 - 841, The workflow currently compiles hbb_common ("Check update metadata verifier") and runs the Python generator test ("Test update metadata script") but never exercises the Rust verifier against the generated rustdesk-update.json; add a new CI step after the Python test that invokes the Rust verifier binary from the hbb_common package to validate the generated metadata (e.g., run cargo in hbb_common to execute the verifier binary or integration test) against the rustdesk-update.json produced by res/test_generate_update_metadata.py so schema/validation drift is caught in CI.src/platform/windows.rs (1)
3691-3694:⚠️ Potential issue | 🟠 Major | 🏗️ Heavy liftDon't unconditionally route verified
.exeupdates through--single-exe.On Line 3693, every verified
.exeis forced into single-exe mode, butupdate_me_(..., true)at Lines 3412-3416 only copies the verified.exeplusORIGIN_PROCESS_EXE. The normal path copies the entire source directory, so any sibling DLLs, Flutter assets, or helper binaries stay old and the install can end up mixed-version or fail at startup. Gate--single-exeon metadata that proves the artifact is standalone, or stage and verify the full payload directory before elevation.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/platform/windows.rs` around lines 3691 - 3694, The current logic forces any verified ".exe" into single-exe mode by building args with UPDATE_SINGLE_EXE_ARG and calling run_uac, which causes mixed-version installs because update_me_ (when called with true) only copies the exe and ORIGIN_PROCESS_EXE; instead, change the decision in the match/extension branch to only use the "--single-exe" path when metadata proves the artifact is standalone (e.g., a manifest flag or a verification function), otherwise stage and verify the full payload directory and invoke run_uac with args that trigger full-directory update; look for symbols extension, UPDATE_SINGLE_EXE_ARG, run_uac, and update_me_ to implement the gate (or add a helper verify_standalone_exe()) and ensure the normal copy-of-source-directory flow is used when not standalone.src/core_main.rs (1)
79-88:⚠️ Potential issue | 🟠 Major | ⚡ Quick winRequire signed sidecars for DMG updates instead of falling back to
LegacyDmg.
parse_macos_update_args()still accepts bare--update <file>.dmgand returnsLegacyDmg, which the macOS update branch later dispatches toplatform::update_from_dmg(). That keeps an unsigned offline-update path alive in the same PR that is supposed to apply signed metadata verification to macOS DMG installs. Reject this form outright, or hide it behind an explicit unsafe/legacy flag.Minimal direction
- (None, None) => Ok(MacosUpdateArgs::LegacyDmg { - dmg_path: dmg_path.clone(), - }), + (None, None) => Err( + "signed metadata is required for DMG updates; pass --metadata and --signature" + .to_owned(), + ),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/core_main.rs` around lines 79 - 88, The match in parse_macos_update_args currently returns MacosUpdateArgs::LegacyDmg when metadata/signature are absent; change this to reject bare DMG updates by returning an Err instead (or gate LegacyDmg behind an explicit unsafe flag such as allow_unsafe_legacy) so unsigned DMG paths are not allowed by default; update parse_macos_update_args and the MacosUpdateArgs enum (remove or mark LegacyDmg as conditional) and ensure callers (e.g., the macOS update branch that may call platform::update_from_dmg) handle the new Err or the explicit legacy flag.src/platform/macos.rs (1)
1211-1218:⚠️ Potential issue | 🟠 Major | ⚡ Quick winDerive the sidecar policy from the active app/package identity.
dmg_sidecar_policy()hard-codesappandallowed_package_idsto"rustdesk", but this verified path otherwise derives runtime identity dynamically. That means signed sidecars for branded/custom clients will be rejected before install even though the metadata contract is supposed to validate the current app/package pair, not just the stock RustDesk one.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/platform/macos.rs` around lines 1211 - 1218, dmg_sidecar_policy() currently hard-codes app and allowed_package_ids to "rustdesk"; change it to derive those values from the runtime/app/package identity instead of literals. Replace the literal "rustdesk" usage in UpdateMetadataPolicy.app and UpdateMetadataPolicy.allowed_package_ids with the current application's app identifier and the current package id(s) obtained from the same identity source used elsewhere in this module (e.g., the runtime identity getter used for verifying signed paths), so signed sidecars for branded/custom clients are accepted.flutter/lib/desktop/widgets/update_progress.dart (1)
56-59:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winThe verified-update localization is still incomplete across
flutter/lib/desktop/widgets/update_progress.dart,src/lang/ar.rs, andsrc/lang/be.rs. The Dart dialog still hard-codes English action/error strings, while the Arabic and Belarusian locale maps leave the new verification-copy entries empty. That produces mixed-language or blank UI in the update flow.src/lang/sc.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winFill the new update-verification strings.
These three locale entries are still mapped to
"", so the security-sensitive update verification flow will render blank text for Sardinian, Slovak, and Slovenian users. Please provide translations or at least English fallbacks in all three files.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/sc.rs` around lines 761 - 762, Replace the empty translations for the update-verification messages in src/lang/sc.rs by supplying Sardinian text or an English fallback for the two tuples ("Verifying update", "") and ("Please wait while {} verifies the update.", ""); update the second string to include the {} placeholder as in the source, ensuring proper punctuation and capitalization so the verification flow shows readable text for Sardinian users.src/lang/sq.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winFix the shared verification-status fallback across all three locales.
"Verifying update"and"Please wait while {} verifies the update."are still empty insrc/lang/sq.rs,src/lang/sr.rs, andsrc/lang/sv.rs, so the Flutter verified-update dialog will show blank text in those locales. Populate each with non-empty fallback strings (English or proper translations) until the locale strings are ready. Based on learnings:flutter/lib/desktop/widgets/update_progress.darttranslates these exact keys, so empty values render blank verification text.Suggested patch
- ("Verifying update", ""), - ("Please wait while {} verifies the update.", ""), + ("Verifying update", "Verifying update"), + ("Please wait while {} verifies the update.", "Please wait while {} verifies the update."),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/sq.rs` around lines 761 - 762, The two localization entries ("Verifying update", "") and ("Please wait while {} verifies the update.", "") in the Albanian file (src/lang/sq.rs) are empty (and likewise in src/lang/sr.rs and src/lang/sv.rs), causing blank text in the Flutter verified-update dialog; update each tuple to provide non-empty fallback strings (either English or proper translations) so the keys used by flutter/lib/desktop/widgets/update_progress.dart render text (e.g., replace "" with "Verifying update" and "Please wait while {} verifies the update." or their translated equivalents) in the tuples in sq.rs, sr.rs, and sv.rs.src/lang/vi.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winFill the Vietnamese verification strings (currently blank on Line 761 and Line 762).
Both new keys have empty values, so the verification UI will show no text during update checks. Please provide Vietnamese translations.
Proposed patch
- ("Verifying update", ""), - ("Please wait while {} verifies the update.", ""), + ("Verifying update", "Đang xác minh bản cập nhật"), + ("Please wait while {} verifies the update.", "Vui lòng chờ trong khi {} xác minh bản cập nhật."),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/vi.rs` around lines 761 - 762, Replace the two empty Vietnamese strings for the localization keys "Verifying update" and "Please wait while {} verifies the update." with proper Vietnamese translations: set "Verifying update" to "Đang xác minh bản cập nhật" and set "Please wait while {} verifies the update." to "Vui lòng chờ trong khi {} đang xác minh bản cập nhật." to ensure the update verification UI displays text.src/updater.rs (2)
242-255:⚠️ Potential issue | 🟠 Major | ⚡ Quick winHonor
update_msion non-Flutter Windows.This regresses the MSI path: Lines 252-255 still hard-code
"exe", butcheck_update()computesupdate_msion Windows andupdate_new_version()still routesupdate_msi == trueintoupdate_me_msi(...). On a non-Flutter MSI install, you'll resolve/download the EXE artifact and then feed that EXE into the MSI installer flow. Please flip this branch to return"msi"whenupdate_msiis true, and update the Windows test below to match.💡 Minimal fix
pub(crate) fn current_update_format(update_msi: bool) -> &'static str { - #[cfg(any(not(target_os = "windows"), all(target_os = "windows", not(feature = "flutter"))))] + #[cfg(not(target_os = "windows"))] let _ = update_msi; @@ #[cfg(all(target_os = "windows", not(feature = "flutter")))] { - "exe" + if update_msi { + "msi" + } else { + "exe" + } }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/updater.rs` around lines 242 - 255, The non-Flutter Windows branch of current_update_format ignores the update_msi argument and always returns "exe", causing MSI installs to be treated as EXE; update current_update_format to consult the update_msi parameter in the #[cfg(all(target_os = "windows", not(feature = "flutter")))] block and return "msi" when update_msi is true (otherwise "exe"), and adjust the corresponding Windows test to expect "msi" when update_msi is true; refer to the function current_update_format and related callers check_update() and update_new_version()/update_me_msi() when making the change.
1052-1068:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winRestore
VERIFIED_UPDATE_ARTIFACTSafter this test.Line 1055 mutates a process-global cache and leaves it changed. Rust tests run in parallel by default, so another test can observe either the cleared map or this test's cached artifact and become order-dependent. Save the original map and restore it in teardown/a guard.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/updater.rs` around lines 1052 - 1068, This test mutates the global VERIFIED_UPDATE_ARTIFACTS without restoring it; wrap the test's mutation by saving the original map (e.g., let original = VERIFIED_UPDATE_ARTIFACTS.lock().unwrap().clone()), perform the clear/cache operations (using verified_artifact and cache_verified_update_artifact), and then restore the original map at teardown (e.g., reassign the locked map back to original) or implement a small RAII guard type that restores the saved value in Drop and instantiate it at the start of the test to guarantee restoration even on panics; ensure you reference VERIFIED_UPDATE_ARTIFACTS, verified_artifact, and cache_verified_update_artifact in the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@flutter/lib/desktop/widgets/update_progress.dart`:
- Around line 263-266: _onError currently only cancels the query timer and shows
the error dialog, leaving a stale downloader entry; before calling
_showUpdateError (and after cancelQueryTimer()), invoke the same teardown used
on success to remove the downloader entry — call the remove-downloader logic
(e.g., the removeDownloader/removeDownloaderEntry method or dispatch the
"remove-downloader" action/IPC) referencing the current download id (from the
downloader state used by _onError) so the downloader record is removed, then
proceed to call _showUpdateError(widget.releasePageUrl, error, showDownloadTip:
true).
In `@src/lang/de.rs`:
- Around line 761-762: Update the i18n entries so the lookup keys and values
match the Flutter lookup and are non-empty: replace the empty value for
"Verifying update" with the correct German translation, and change the key
"Please wait while {} verifies the update." to the exact lookup key "Please wait
while {$appName} verifies the update." and provide its German translation; apply
the same change to the corresponding entries in the other locale files (Greek,
Esperanto, Spanish, Estonian) so the verified-update dialog can find and display
the localized strings.
In `@src/platform/windows.rs`:
- Around line 2088-2092: The code uses crate::read_custom_client(...) (assigned
to is_valid_custom_client) to decide whether the staged custom.txt is valid, but
read_custom_client only indicates the "is custom client" flag, not
parse/signature success; change the logic to first verify/parse the file with an
API that reports success (for example call a verify/parse function such as
crate::verify_custom_client(...) or crate::parse_and_verify_custom_client(...)
on the custom_client_config string and check its Result/Ok) and only after
successful verification consult the "is custom client" flag (via
read_custom_client or from the parsed result) before aborting the update path;
update the condition around custom_txt_path, custom_client_config,
is_valid_custom_client accordingly so a valid signed custom.txt that isn’t a
custom client does not cause an abort.
---
Outside diff comments:
In `@src/common.rs`:
- Around line 2316-2390: read_custom_client currently returns is_custom_client
(branding) which causes valid signed configs with default/“RustDesk” app-name to
be treated as invalid; change the function to return true when
decoding/signature/JSON parsing succeed (i.e., treat the return value as “config
valid”), and stop using the return value to convey branding. Concretely: in
read_custom_client(...) remove using is_custom_client as the function return and
instead return true at the end whenever processing completed successfully (keep
setting config::APP_NAME and crate::is_custom_client() state as before); leave
is_custom_client/local variable only to update branding state via whatever
crate::is_custom_client() mechanism exists. Then update the downstream caller
that currently assigns read_custom_client(...) into is_valid_custom_client to
treat that return as validity-only and call crate::is_custom_client() separately
when it needs branding info. Also add a regression test that verifies a signed
config with the default app-name parses as valid.
In `@src/platform/privileges_scripts/update.scpt`:
- Around line 19-31: The script currently removes the previous app bundle inside
install_staged_bundle before writing/loading plists (write_daemon_plist,
write_agent_plist, load_service, load_agent), which can leave the system without
a working daemon if any later step fails; to fix, stop deleting $old_bundle in
install_staged_bundle and instead perform the rm -rf "$old_bundle" only after
load_service and load_agent succeed (i.e., append the deletion after load_agent
in the sh command), or alternatively enhance the cleanup_verified EXIT trap to
detect failure and restore $old_bundle and the previous launchd state (recreate
previous plist files and run launchctl bootstrap/load for the old agent/daemon)
so the previous bundle and services are restored on error.
---
Duplicate comments:
In @.github/workflows/flutter-build.yml:
- Around line 891-901: The workflow hardcodes release URLs to rustdesk/rustdesk
which causes generated fragments and the verifier to be invalid for other
repositories; update the job that runs the fragment generation in
.github/workflows/flutter-build.yml to derive the repo from an env var (e.g.,
GITHUB_REPOSITORY or a new REPO env) and pass that repository into
res/generate_update_metadata.py (add a --repository or --upstream-repo flag),
then update res/generate_update_metadata.py to accept/validate that repository
instead of assuming rustdesk/rustdesk and make
res/test_generate_update_metadata.py use fixtures or a parameterized repo value
matching the new flag so the tests catch non-rustdesk repos; ensure all places
referencing the hardcoded string are replaced (workflow generation lines,
generate_update_metadata.py parser/validator, and test file).
- Around line 837-841: The workflow currently compiles hbb_common ("Check update
metadata verifier") and runs the Python generator test ("Test update metadata
script") but never exercises the Rust verifier against the generated
rustdesk-update.json; add a new CI step after the Python test that invokes the
Rust verifier binary from the hbb_common package to validate the generated
metadata (e.g., run cargo in hbb_common to execute the verifier binary or
integration test) against the rustdesk-update.json produced by
res/test_generate_update_metadata.py so schema/validation drift is caught in CI.
In @.github/workflows/flutter-tag.yml:
- Around line 17-19: The workflow currently forces publish/update metadata for
every tag build by setting publish-update-metadata (and implicitly the
signed-metadata path) to true; change this to not be hardcoded—make
publish-update-metadata (or the specific publish-signed-update-metadata input)
conditional or default to false and only set it true when platform signing is
available (e.g., guard it with a conditional expression that checks an env flag
like SIGNING_AVAILABLE, a job output indicating signing artifacts were produced,
or the presence of the signing jobs), so the producer upload jobs
(upload-artifact / upload-tag) run when appropriate and the publish job won’t
fail downloading missing artifacts.
In `@src/core_main.rs`:
- Around line 79-88: The match in parse_macos_update_args currently returns
MacosUpdateArgs::LegacyDmg when metadata/signature are absent; change this to
reject bare DMG updates by returning an Err instead (or gate LegacyDmg behind an
explicit unsafe flag such as allow_unsafe_legacy) so unsigned DMG paths are not
allowed by default; update parse_macos_update_args and the MacosUpdateArgs enum
(remove or mark LegacyDmg as conditional) and ensure callers (e.g., the macOS
update branch that may call platform::update_from_dmg) handle the new Err or the
explicit legacy flag.
In `@src/lang/sc.rs`:
- Around line 761-762: Replace the empty translations for the
update-verification messages in src/lang/sc.rs by supplying Sardinian text or an
English fallback for the two tuples ("Verifying update", "") and ("Please wait
while {} verifies the update.", ""); update the second string to include the {}
placeholder as in the source, ensuring proper punctuation and capitalization so
the verification flow shows readable text for Sardinian users.
In `@src/lang/sq.rs`:
- Around line 761-762: The two localization entries ("Verifying update", "") and
("Please wait while {} verifies the update.", "") in the Albanian file
(src/lang/sq.rs) are empty (and likewise in src/lang/sr.rs and src/lang/sv.rs),
causing blank text in the Flutter verified-update dialog; update each tuple to
provide non-empty fallback strings (either English or proper translations) so
the keys used by flutter/lib/desktop/widgets/update_progress.dart render text
(e.g., replace "" with "Verifying update" and "Please wait while {} verifies the
update." or their translated equivalents) in the tuples in sq.rs, sr.rs, and
sv.rs.
In `@src/lang/vi.rs`:
- Around line 761-762: Replace the two empty Vietnamese strings for the
localization keys "Verifying update" and "Please wait while {} verifies the
update." with proper Vietnamese translations: set "Verifying update" to "Đang
xác minh bản cập nhật" and set "Please wait while {} verifies the update." to
"Vui lòng chờ trong khi {} đang xác minh bản cập nhật." to ensure the update
verification UI displays text.
In `@src/platform/macos.rs`:
- Around line 1211-1218: dmg_sidecar_policy() currently hard-codes app and
allowed_package_ids to "rustdesk"; change it to derive those values from the
runtime/app/package identity instead of literals. Replace the literal "rustdesk"
usage in UpdateMetadataPolicy.app and UpdateMetadataPolicy.allowed_package_ids
with the current application's app identifier and the current package id(s)
obtained from the same identity source used elsewhere in this module (e.g., the
runtime identity getter used for verifying signed paths), so signed sidecars for
branded/custom clients are accepted.
In `@src/platform/windows.rs`:
- Around line 3691-3694: The current logic forces any verified ".exe" into
single-exe mode by building args with UPDATE_SINGLE_EXE_ARG and calling run_uac,
which causes mixed-version installs because update_me_ (when called with true)
only copies the exe and ORIGIN_PROCESS_EXE; instead, change the decision in the
match/extension branch to only use the "--single-exe" path when metadata proves
the artifact is standalone (e.g., a manifest flag or a verification function),
otherwise stage and verify the full payload directory and invoke run_uac with
args that trigger full-directory update; look for symbols extension,
UPDATE_SINGLE_EXE_ARG, run_uac, and update_me_ to implement the gate (or add a
helper verify_standalone_exe()) and ensure the normal copy-of-source-directory
flow is used when not standalone.
In `@src/updater.rs`:
- Around line 242-255: The non-Flutter Windows branch of current_update_format
ignores the update_msi argument and always returns "exe", causing MSI installs
to be treated as EXE; update current_update_format to consult the update_msi
parameter in the #[cfg(all(target_os = "windows", not(feature = "flutter")))]
block and return "msi" when update_msi is true (otherwise "exe"), and adjust the
corresponding Windows test to expect "msi" when update_msi is true; refer to the
function current_update_format and related callers check_update() and
update_new_version()/update_me_msi() when making the change.
- Around line 1052-1068: This test mutates the global VERIFIED_UPDATE_ARTIFACTS
without restoring it; wrap the test's mutation by saving the original map (e.g.,
let original = VERIFIED_UPDATE_ARTIFACTS.lock().unwrap().clone()), perform the
clear/cache operations (using verified_artifact and
cache_verified_update_artifact), and then restore the original map at teardown
(e.g., reassign the locked map back to original) or implement a small RAII guard
type that restores the saved value in Drop and instantiate it at the start of
the test to guarantee restoration even on panics; ensure you reference
VERIFIED_UPDATE_ARTIFACTS, verified_artifact, and cache_verified_update_artifact
in the change.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 13dc7b3b-19ed-471d-b61e-5d586c62322c
📒 Files selected for processing (67)
.github/workflows/flutter-build.yml.github/workflows/flutter-tag.ymlflutter/lib/desktop/widgets/update_cancel_controller.dartflutter/lib/desktop/widgets/update_progress.dartlibs/hbb_commonres/generate_update_metadata.pyres/test_generate_update_metadata.pysrc/common.rssrc/core_main.rssrc/flutter_ffi.rssrc/hbbs_http.rssrc/hbbs_http/downloader.rssrc/hbbs_http/http_client.rssrc/lang/ar.rssrc/lang/be.rssrc/lang/bg.rssrc/lang/ca.rssrc/lang/cn.rssrc/lang/cs.rssrc/lang/da.rssrc/lang/de.rssrc/lang/el.rssrc/lang/eo.rssrc/lang/es.rssrc/lang/et.rssrc/lang/eu.rssrc/lang/fa.rssrc/lang/fi.rssrc/lang/fr.rssrc/lang/ge.rssrc/lang/gu.rssrc/lang/he.rssrc/lang/hi.rssrc/lang/hr.rssrc/lang/hu.rssrc/lang/id.rssrc/lang/it.rssrc/lang/ja.rssrc/lang/ko.rssrc/lang/kz.rssrc/lang/lt.rssrc/lang/lv.rssrc/lang/ml.rssrc/lang/nb.rssrc/lang/nl.rssrc/lang/pl.rssrc/lang/pt_PT.rssrc/lang/ptbr.rssrc/lang/ro.rssrc/lang/ru.rssrc/lang/sc.rssrc/lang/sk.rssrc/lang/sl.rssrc/lang/sq.rssrc/lang/sr.rssrc/lang/sv.rssrc/lang/ta.rssrc/lang/template.rssrc/lang/th.rssrc/lang/tr.rssrc/lang/tw.rssrc/lang/uk.rssrc/lang/vi.rssrc/platform/macos.rssrc/platform/privileges_scripts/update.scptsrc/platform/windows.rssrc/updater.rs
e7ca66d to
c34cd1f
Compare
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
res/generate_update_metadata.py (1)
287-295: 🧹 Nitpick | 🔵 Trivial | 💤 Low valuePreserve exception context with explicit chain suppression.
The
raise SystemExit(1)withoutfromloses the exception chain context. While the error message is printed to stderr, usingfrom Noneexplicitly suppresses the chain for cleaner output and satisfies linter rules.🔧 Suggested fix
except Exception as error: print(str(error), file=sys.stderr) - raise SystemExit(1) + raise SystemExit(1) from None🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@res/generate_update_metadata.py` around lines 287 - 295, In the top-level guard that calls main(), update the generic exception handler (the "except Exception as error" block that prints the error) to explicitly suppress exception chaining by replacing the bare "raise SystemExit(1)" with "raise SystemExit(1) from None" so the original traceback isn't re-raised while preserving the printed error; leave the "except SystemExit: raise" path unchanged.Source: Linters/SAST tools
♻️ Duplicate comments (12)
src/flutter_ffi.rs (1)
2875-2880:⚠️ Potential issue | 🟠 Major | 🏗️ Heavy liftPreserve the verified artifact payload across the FFI boundary.
This branch still returns only
artifact.url, but the later"download-new-version"and"update-me"paths re-resolve metadata from that URL instead of consuming the original verified selection. That means the Flutter flow never carries the trustedsize/sha256forward, which undermines the offline/manual-update path this PR is trying to add. Return an opaque serialized artifact/token here and make both setters consume that payload instead of looking the artifact up again by URL.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/flutter_ffi.rs` around lines 2875 - 2880, The branch handling key.strip_prefix("verified-download-url-") currently returns only artifact.url which loses the verified artifact payload; instead serialize and return an opaque token/payload that contains the entire VerifiedUpdateArtifact (e.g. produced by verified_update_artifact_for_release_page_url), and update the consumers of this key (the "download-new-version" and "update-me" setter paths) to accept and deserialize that opaque payload rather than re-resolving by URL; specifically, change the branch to return a serialized artifact/token (not just artifact.url) from verified_update_artifact_for_release_page_url, and change the handlers that previously re-fetch metadata by URL to consume the deserialized VerifiedUpdateArtifact and use its size/sha256/url directly.src/lang/ar.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winPopulate the new verification-copy translations.
Both locale maps still leave the new verification strings empty, so this dialog falls back to English instead of the target language.
src/lang/ar.rs#L761-L762: add Arabic translations for both entries and keep{}unchanged in the second string.src/lang/be.rs#L761-L762: add Belarusian translations for both entries and keep{}unchanged in the second string.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/ar.rs` around lines 761 - 762, For each affected locale map, replace the empty strings for the two verification entries with proper translations while preserving the placeholder braces `{}` exactly as in the original: in src/lang/ar.rs (lines 761-762) set ("Verifying update", "<Arabic translation for 'Verifying update'>") and ("Please wait while {} verifies the update.", "<Arabic translation keeping {} unchanged>"); and in src/lang/be.rs (lines 761-762) set ("Verifying update", "<Belarusian translation for 'Verifying update'>") and ("Please wait while {} verifies the update.", "<Belarusian translation keeping {} unchanged>"). Ensure the translations are idiomatic and do not alter or remove the `{}` placeholder.flutter/lib/desktop/widgets/update_progress.dart (1)
167-169:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winLocalize the error-dialog action labels.
These buttons still bypass the locale tables, so the verified-update error flow shows English actions in non-English locales.
♻️ Minimal fix
- dialogButton('Download', onPressed: jumplink), - if (showRetry) dialogButton('Retry', onPressed: retry), - dialogButton('Close', onPressed: close), + dialogButton(translate('Download'), onPressed: jumplink), + if (showRetry) dialogButton(translate('Retry'), onPressed: retry), + dialogButton(translate('Close'), onPressed: close),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@flutter/lib/desktop/widgets/update_progress.dart` around lines 167 - 169, Replace the hard-coded English labels in the dialogButton calls with localized strings from the app's localization class so the error dialog respects locale tables: in update_progress.dart update the three calls inside the dialogButtons list (the dialogButton('Download', onPressed: jumplink), dialogButton('Retry', onPressed: retry) guarded by showRetry, and dialogButton('Close', onPressed: close)) to use the appropriate localization getters (for example AppLocalizations.of(context).download, .retry, .close or the project's S.of(context)/context.l10n equivalents), ensuring you import the localization class and keep the same callbacks and showRetry conditional.src/lang/ptbr.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winReplace empty update-verification translations to avoid blank UI text.
At Line 761 and Line 762 in all three locale files, both new keys map to empty strings, which causes empty status/header text during update verification unless a separate non-empty fallback path exists.
src/lang/ptbr.rs#L761-L762: provide pt-BR values (or temporarily use English fallback text) while preserving the{}placeholder.src/lang/ro.rs#L761-L762: provide Romanian values (or temporarily use English fallback text) while preserving the{}placeholder.src/lang/ru.rs#L761-L762: provide Russian values (or temporarily use English fallback text) while preserving the{}placeholder.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/ptbr.rs` around lines 761 - 762, Provide non-empty translations for the two update-verification keys ("Verifying update" and "Please wait while {} verifies the update.") in each affected locale, preserving the {} placeholder; specifically: in src/lang/ptbr.rs (lines 761-762) add Portuguese text (or temporary English fallback) for both keys and keep the {} intact, in src/lang/ro.rs (lines 761-762) add Romanian text (or temporary English fallback) for both keys and keep the {} intact, and in src/lang/ru.rs (lines 761-762) add Russian text (or temporary English fallback) for both keys and keep the {} intact.src/lang/bg.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winFill the new update-verification strings in the affected locales.
These four locale entries are still empty, so the verification UI will render blank text. Please add non-empty translations and keep the
{}placeholder intact in the second string.
src/lang/bg.rs#L761-L762: provide Bulgarian text for both keys.src/lang/ca.rs#L761-L762: provide Catalan text for both keys.src/lang/cs.rs#L761-L762: provide Czech text for both keys.src/lang/da.rs#L761-L762: provide Danish text for both keys.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/bg.rs` around lines 761 - 762, Populate the two empty localization entries for each affected file so the verification UI shows text; specifically, in src/lang/bg.rs (lines 761-762) replace ("Verifying update", "") with ("Потвърждение на актуализацията", "") and replace ("Please wait while {} verifies the update.", "") with ("Моля изчакайте, докато {} проверява актуализацията.", ""); in src/lang/ca.rs (lines 761-762) replace with ("Verificant la actualització", "") and ("Espereu mentre {} verifica l'actualització.", ""); in src/lang/cs.rs (lines 761-762) replace with ("Ověřování aktualizace", "") and ("Počkejte, prosím, zatímco {} ověřuje aktualizaci.", ""); and in src/lang/da.rs (lines 761-762) replace with ("Verificering af opdatering", "") and ("Vent venligst, mens {} verificerer opdateringen.", ""); ensure the {} placeholder is preserved exactly and that both tuple elements are non-empty strings.src/lang/sk.rs (1)
761-762:⚠️ Potential issue | 🟡 MinorDuplicate: provide Slovak translation or fallback for verification messages.
Line 761 and Line 762 are empty, which keeps the update verification UI blank for Slovak users. This issue was already flagged previously; please fill both values and keep
{}unchanged in the second string.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/sk.rs` around lines 761 - 762, Provide Slovak translations for the two empty entries in the localization tuple: replace the first empty string with a Slovak translation of "Verifying update" (e.g., "Overovanie aktualizácie") and replace the second empty string with a Slovak translation of "Please wait while {} verifies the update." keeping the placeholder {} exactly as-is (e.g., "Počkajte, kým {} overí aktualizáciu.").src/lang/sl.rs (1)
761-762:⚠️ Potential issue | 🟡 MinorDuplicate: avoid blank Slovenian verification strings in security-sensitive flow.
Line 761 and Line 762 are empty, so users won’t see verification progress text during update validation. This was already reported; please add Slovenian text or English fallback and preserve
{}in Line 762.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/sl.rs` around lines 761 - 762, Add Slovenian translations for the two translation entries "Verifying update" and "Please wait while {} verifies the update." in src/lang/sl.rs (replace the current empty strings) and ensure the second string preserves the `{}` placeholder exactly; alternately, if unsure of the Slovenian phrasing, set the second entry to the English fallback "Please wait while {} verifies the update." to avoid an empty UI string.src/lang/sc.rs (1)
761-762:⚠️ Potential issue | 🟡 MinorDuplicate: keep non-empty fallback text for update verification strings.
Line 761 and Line 762 are still empty, so Sardinian users will see blank verification status text. This was already reported earlier; please apply either Sardinian translations or English fallback while preserving
{}.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/sc.rs` around lines 761 - 762, The two Sardinian translation entries for the status strings ("Verifying update", "") and ("Please wait while {} verifies the update.", "") should not be empty; replace the empty second elements with non-empty Sardinian translations or an English fallback preserving the placeholder — e.g. set the second element for "Verifying update" to "Verifying update" (or Sardinian) and for "Please wait while {} verifies the update." to "Please wait while {} verifies the update." ensuring the {} placeholder is left intact and not altered.src/lang/de.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winShared i18n root cause: verification strings are blank and the second key uses a non-runtime placeholder token.
These entries can render blank text and may miss lookup if runtime expects{$appName}.
src/lang/de.rs#L761-L762: set non-empty values and change key toPlease wait while {$appName} verifies the update..src/lang/el.rs#L761-L762: set non-empty values and change key toPlease wait while {$appName} verifies the update..src/lang/eo.rs#L761-L762: set non-empty values and change key toPlease wait while {$appName} verifies the update..src/lang/es.rs#L761-L762: set non-empty values and change key toPlease wait while {$appName} verifies the update..src/lang/et.rs#L761-L762: set non-empty values and change key toPlease wait while {$appName} verifies the update..🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/de.rs` around lines 761 - 762, For each affected i18n file update the two entries so they are non-empty and use the runtime placeholder `{$appName}`: in src/lang/de.rs (761-762) replace the pair ("Verifying update", "") and ("Please wait while {} verifies the update.", "") with non-empty German translations and change the second key to "Please wait while {$appName} verifies the update."; do the same in src/lang/el.rs (761-762), src/lang/eo.rs (761-762), src/lang/es.rs (761-762), and src/lang/et.rs (761-762) — provide appropriate localized text for "Verifying update" and for "Please wait while {$appName} verifies the update." in each file.src/lang/sq.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winShared root cause: newly added update-verification locale entries are empty strings.
The same issue appears across these locales and can render blank verification messaging in the update UI.
src/lang/sq.rs#L761-L762: replace both""values with Albanian translations or temporary English fallbacks.src/lang/sr.rs#L761-L762: replace both""values with Serbian translations or temporary English fallbacks.src/lang/sv.rs#L761-L762: replace both""values with Swedish translations or temporary English fallbacks.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/sq.rs` around lines 761 - 762, The two newly added locale entries at src/lang/sq.rs lines 761-762 currently use empty strings; replace both "" values with proper Albanian translations (or temporary English fallbacks: "Verifying update" and "Please wait while {} verifies the update.") so the verification UI isn’t blank. Do the same for the sibling sites: in src/lang/sr.rs lines 761-762 replace both "" values with Serbian translations or the same English fallbacks, and in src/lang/sv.rs lines 761-762 replace both "" values with Swedish translations or the same English fallbacks.src/lang/ge.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winKeep the verified-update strings aligned with the runtime lookup.
flutter/lib/desktop/widgets/update_progress.dartlooks upVerifying updateandPlease wait while {$appName} verifies the update.exactly, but these locale rows still use empty values and the second key still has{}. That can leave the verification dialog blank or miss the lookup.
src/lang/ge.rs#L761-L762: change the second key toPlease wait while {$appName} verifies the update.and give both entries non-empty text.src/lang/eu.rs#L761-L762: same fix.src/lang/fa.rs#L761-L762: same fix.src/lang/fi.rs#L761-L762: same fix.src/lang/fr.rs#L761-L762: same fix.Based on the runtime lookup in
flutter/lib/desktop/widgets/update_progress.dart, these keys must match exactly.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/ge.rs` around lines 761 - 762, For each listed locale file update the two entries so they exactly match the runtime lookup and provide non-empty translations: in src/lang/ge.rs (761-762), src/lang/eu.rs (761-762), src/lang/fa.rs (761-762), src/lang/fi.rs (761-762) and src/lang/fr.rs (761-762) replace the pair ("Verifying update", "") and ("Please wait while {} verifies the update.", "") with ("Verifying update", "<appropriate non-empty translation for 'Verifying update'>") and ("Please wait while {$appName} verifies the update.", "<appropriate non-empty translation for 'Please wait while {$appName} verifies the update.'>") so the keys match the lookup in flutter/lib/desktop/widgets/update_progress.dart and supply actual text for both entries.src/lang/gu.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winShared i18n regression in verification dialog keys across five locale maps.
All affected files usePlease wait while {} verifies the update.while runtime requestsPlease wait while {$appName} verifies the update., and each new value is empty, so locale lookup and localized rendering both regress in this dialog.
src/lang/gu.rs#L761-L762: change the key token to{$appName}and provide non-empty Gujarati values.src/lang/he.rs#L761-L762: change the key token to{$appName}and provide non-empty Hebrew values.src/lang/hi.rs#L761-L762: change the key token to{$appName}and provide non-empty Hindi values.src/lang/hr.rs#L761-L762: change the key token to{$appName}and provide non-empty Croatian values.src/lang/hu.rs#L761-L762: change the key token to{$appName}and provide non-empty Hungarian values.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/gu.rs` around lines 761 - 762, Replace the incorrect token "{}" with the runtime token "{$appName}" and supply non-empty localized Gujarati/Hebrew/Hindi/Croatian/Hungarian strings for the verification dialog entry in each locale file: in src/lang/gu.rs (lines 761-762) change the tuple ("Please wait while {} verifies the update.", "") to use "{$appName}" and a proper Gujarati translation; in src/lang/he.rs (lines 761-762) make the same token replacement and add a Hebrew translation; in src/lang/hi.rs (lines 761-762) replace with "{$appName}" and add a Hindi translation; in src/lang/hr.rs (lines 761-762) replace with "{$appName}" and add a Croatian translation; and in src/lang/hu.rs (lines 761-762) replace with "{$appName}" and add a Hungarian translation so the runtime key matches and the value is non-empty.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/flutter-build.yml:
- Around line 884-901: In the "Generate update metadata fragments" job replace
the hardcoded artifact base URL
"https://github.com/rustdesk/rustdesk/releases/download" in all python fragment
runs with the parameterized GitHub server/repo expression "${{ github.server_url
}}/${{ github.repository }}/releases/download" so each fragment command (the
python res/generate_update_metadata.py fragment invocations) builds artifact
URLs using "${{ github.server_url }}/${{ github.repository
}}/releases/download/${TAG_NAME}/rustdesk-${VERSION}-..." instead of the fixed
upstream URL; keep the rest of each command identical.
In @.github/workflows/flutter-tag.yml:
- Around line 17-19: The workflow currently forces publish-update-metadata: true
into flutter-build.yml which causes the publish-signed-update-metadata job
(condition: if: inputs.upload-artifact && inputs.publish-update-metadata) to run
and fail on forks missing secrets.RUSTDESK_UPDATE_ED25519_SEED when
res/generate_update_metadata.py runs; fix this by adding a workflow_dispatch
input publish-update-metadata (default: false) to the calling workflow and pass
that input through to flutter-build.yml so forks can opt in, or alternatively
add a guard in the publish-signed-update-metadata job to check
secrets.RUSTDESK_UPDATE_ED25519_SEED and skip the signing step if the secret is
empty (so the job only attempts signing when the seed exists).
In `@src/lang/tr.rs`:
- Around line 761-762: Fill in the missing translations for the two
update-verification keys in both files: in src/lang/tr.rs (lines 761-762)
replace the empty strings with Turkish translations "Güncelleme doğrulanıyor"
for "Verifying update" and "Lütfen {} güncellemeyi doğrularken bekleyiniz." for
"Please wait while {} verifies the update." and in src/lang/tw.rs (lines
761-762) replace the empty strings with Traditional Chinese translations
"正在驗證更新" for "Verifying update" and "請稍候,{} 正在驗證更新。" for "Please wait while {}
verifies the update."; preserve the placeholder {} exactly in both replacements
so the UI interpolation in update_progress.dart continues to work.
In `@src/updater.rs`:
- Around line 444-455: The function get_cached_verified_update_artifact
currently accepts an unused query parameter; remove the unused parameter to
simplify the API: change the signature to fn
get_cached_verified_update_artifact(download_url: &str) ->
Option<VerifiedUpdateArtifact>, delete the unused let _ = query; line, and
update its single caller verified_update_artifact_for_download_url_with_query to
call get_cached_verified_update_artifact(download_url) (remove the query
argument). Ensure any other references/tests are updated to the new signature.
---
Outside diff comments:
In `@res/generate_update_metadata.py`:
- Around line 287-295: In the top-level guard that calls main(), update the
generic exception handler (the "except Exception as error" block that prints the
error) to explicitly suppress exception chaining by replacing the bare "raise
SystemExit(1)" with "raise SystemExit(1) from None" so the original traceback
isn't re-raised while preserving the printed error; leave the "except
SystemExit: raise" path unchanged.
---
Duplicate comments:
In `@flutter/lib/desktop/widgets/update_progress.dart`:
- Around line 167-169: Replace the hard-coded English labels in the dialogButton
calls with localized strings from the app's localization class so the error
dialog respects locale tables: in update_progress.dart update the three calls
inside the dialogButtons list (the dialogButton('Download', onPressed:
jumplink), dialogButton('Retry', onPressed: retry) guarded by showRetry, and
dialogButton('Close', onPressed: close)) to use the appropriate localization
getters (for example AppLocalizations.of(context).download, .retry, .close or
the project's S.of(context)/context.l10n equivalents), ensuring you import the
localization class and keep the same callbacks and showRetry conditional.
In `@src/flutter_ffi.rs`:
- Around line 2875-2880: The branch handling
key.strip_prefix("verified-download-url-") currently returns only artifact.url
which loses the verified artifact payload; instead serialize and return an
opaque token/payload that contains the entire VerifiedUpdateArtifact (e.g.
produced by verified_update_artifact_for_release_page_url), and update the
consumers of this key (the "download-new-version" and "update-me" setter paths)
to accept and deserialize that opaque payload rather than re-resolving by URL;
specifically, change the branch to return a serialized artifact/token (not just
artifact.url) from verified_update_artifact_for_release_page_url, and change the
handlers that previously re-fetch metadata by URL to consume the deserialized
VerifiedUpdateArtifact and use its size/sha256/url directly.
In `@src/lang/ar.rs`:
- Around line 761-762: For each affected locale map, replace the empty strings
for the two verification entries with proper translations while preserving the
placeholder braces `{}` exactly as in the original: in src/lang/ar.rs (lines
761-762) set ("Verifying update", "<Arabic translation for 'Verifying update'>")
and ("Please wait while {} verifies the update.", "<Arabic translation keeping
{} unchanged>"); and in src/lang/be.rs (lines 761-762) set ("Verifying update",
"<Belarusian translation for 'Verifying update'>") and ("Please wait while {}
verifies the update.", "<Belarusian translation keeping {} unchanged>"). Ensure
the translations are idiomatic and do not alter or remove the `{}` placeholder.
In `@src/lang/bg.rs`:
- Around line 761-762: Populate the two empty localization entries for each
affected file so the verification UI shows text; specifically, in src/lang/bg.rs
(lines 761-762) replace ("Verifying update", "") with ("Потвърждение на
актуализацията", "") and replace ("Please wait while {} verifies the update.",
"") with ("Моля изчакайте, докато {} проверява актуализацията.", ""); in
src/lang/ca.rs (lines 761-762) replace with ("Verificant la actualització", "")
and ("Espereu mentre {} verifica l'actualització.", ""); in src/lang/cs.rs
(lines 761-762) replace with ("Ověřování aktualizace", "") and ("Počkejte,
prosím, zatímco {} ověřuje aktualizaci.", ""); and in src/lang/da.rs (lines
761-762) replace with ("Verificering af opdatering", "") and ("Vent venligst,
mens {} verificerer opdateringen.", ""); ensure the {} placeholder is preserved
exactly and that both tuple elements are non-empty strings.
In `@src/lang/de.rs`:
- Around line 761-762: For each affected i18n file update the two entries so
they are non-empty and use the runtime placeholder `{$appName}`: in
src/lang/de.rs (761-762) replace the pair ("Verifying update", "") and ("Please
wait while {} verifies the update.", "") with non-empty German translations and
change the second key to "Please wait while {$appName} verifies the update."; do
the same in src/lang/el.rs (761-762), src/lang/eo.rs (761-762), src/lang/es.rs
(761-762), and src/lang/et.rs (761-762) — provide appropriate localized text for
"Verifying update" and for "Please wait while {$appName} verifies the update."
in each file.
In `@src/lang/ge.rs`:
- Around line 761-762: For each listed locale file update the two entries so
they exactly match the runtime lookup and provide non-empty translations: in
src/lang/ge.rs (761-762), src/lang/eu.rs (761-762), src/lang/fa.rs (761-762),
src/lang/fi.rs (761-762) and src/lang/fr.rs (761-762) replace the pair
("Verifying update", "") and ("Please wait while {} verifies the update.", "")
with ("Verifying update", "<appropriate non-empty translation for 'Verifying
update'>") and ("Please wait while {$appName} verifies the update.",
"<appropriate non-empty translation for 'Please wait while {$appName} verifies
the update.'>") so the keys match the lookup in
flutter/lib/desktop/widgets/update_progress.dart and supply actual text for both
entries.
In `@src/lang/gu.rs`:
- Around line 761-762: Replace the incorrect token "{}" with the runtime token
"{$appName}" and supply non-empty localized
Gujarati/Hebrew/Hindi/Croatian/Hungarian strings for the verification dialog
entry in each locale file: in src/lang/gu.rs (lines 761-762) change the tuple
("Please wait while {} verifies the update.", "") to use "{$appName}" and a
proper Gujarati translation; in src/lang/he.rs (lines 761-762) make the same
token replacement and add a Hebrew translation; in src/lang/hi.rs (lines
761-762) replace with "{$appName}" and add a Hindi translation; in
src/lang/hr.rs (lines 761-762) replace with "{$appName}" and add a Croatian
translation; and in src/lang/hu.rs (lines 761-762) replace with "{$appName}" and
add a Hungarian translation so the runtime key matches and the value is
non-empty.
In `@src/lang/ptbr.rs`:
- Around line 761-762: Provide non-empty translations for the two
update-verification keys ("Verifying update" and "Please wait while {} verifies
the update.") in each affected locale, preserving the {} placeholder;
specifically: in src/lang/ptbr.rs (lines 761-762) add Portuguese text (or
temporary English fallback) for both keys and keep the {} intact, in
src/lang/ro.rs (lines 761-762) add Romanian text (or temporary English fallback)
for both keys and keep the {} intact, and in src/lang/ru.rs (lines 761-762) add
Russian text (or temporary English fallback) for both keys and keep the {}
intact.
In `@src/lang/sc.rs`:
- Around line 761-762: The two Sardinian translation entries for the status
strings ("Verifying update", "") and ("Please wait while {} verifies the
update.", "") should not be empty; replace the empty second elements with
non-empty Sardinian translations or an English fallback preserving the
placeholder — e.g. set the second element for "Verifying update" to "Verifying
update" (or Sardinian) and for "Please wait while {} verifies the update." to
"Please wait while {} verifies the update." ensuring the {} placeholder is left
intact and not altered.
In `@src/lang/sk.rs`:
- Around line 761-762: Provide Slovak translations for the two empty entries in
the localization tuple: replace the first empty string with a Slovak translation
of "Verifying update" (e.g., "Overovanie aktualizácie") and replace the second
empty string with a Slovak translation of "Please wait while {} verifies the
update." keeping the placeholder {} exactly as-is (e.g., "Počkajte, kým {} overí
aktualizáciu.").
In `@src/lang/sl.rs`:
- Around line 761-762: Add Slovenian translations for the two translation
entries "Verifying update" and "Please wait while {} verifies the update." in
src/lang/sl.rs (replace the current empty strings) and ensure the second string
preserves the `{}` placeholder exactly; alternately, if unsure of the Slovenian
phrasing, set the second entry to the English fallback "Please wait while {}
verifies the update." to avoid an empty UI string.
In `@src/lang/sq.rs`:
- Around line 761-762: The two newly added locale entries at src/lang/sq.rs
lines 761-762 currently use empty strings; replace both "" values with proper
Albanian translations (or temporary English fallbacks: "Verifying update" and
"Please wait while {} verifies the update.") so the verification UI isn’t blank.
Do the same for the sibling sites: in src/lang/sr.rs lines 761-762 replace both
"" values with Serbian translations or the same English fallbacks, and in
src/lang/sv.rs lines 761-762 replace both "" values with Swedish translations or
the same English fallbacks.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 9fc56567-40e4-40f8-9c06-1245b4b4aece
📒 Files selected for processing (67)
.github/workflows/flutter-build.yml.github/workflows/flutter-tag.ymlflutter/lib/desktop/widgets/update_cancel_controller.dartflutter/lib/desktop/widgets/update_progress.dartlibs/hbb_commonres/generate_update_metadata.pyres/test_generate_update_metadata.pysrc/common.rssrc/core_main.rssrc/flutter_ffi.rssrc/hbbs_http.rssrc/hbbs_http/downloader.rssrc/hbbs_http/http_client.rssrc/lang/ar.rssrc/lang/be.rssrc/lang/bg.rssrc/lang/ca.rssrc/lang/cn.rssrc/lang/cs.rssrc/lang/da.rssrc/lang/de.rssrc/lang/el.rssrc/lang/eo.rssrc/lang/es.rssrc/lang/et.rssrc/lang/eu.rssrc/lang/fa.rssrc/lang/fi.rssrc/lang/fr.rssrc/lang/ge.rssrc/lang/gu.rssrc/lang/he.rssrc/lang/hi.rssrc/lang/hr.rssrc/lang/hu.rssrc/lang/id.rssrc/lang/it.rssrc/lang/ja.rssrc/lang/ko.rssrc/lang/kz.rssrc/lang/lt.rssrc/lang/lv.rssrc/lang/ml.rssrc/lang/nb.rssrc/lang/nl.rssrc/lang/pl.rssrc/lang/pt_PT.rssrc/lang/ptbr.rssrc/lang/ro.rssrc/lang/ru.rssrc/lang/sc.rssrc/lang/sk.rssrc/lang/sl.rssrc/lang/sq.rssrc/lang/sr.rssrc/lang/sv.rssrc/lang/ta.rssrc/lang/template.rssrc/lang/th.rssrc/lang/tr.rssrc/lang/tw.rssrc/lang/uk.rssrc/lang/vi.rssrc/platform/macos.rssrc/platform/privileges_scripts/update.scptsrc/platform/windows.rssrc/updater.rs
c34cd1f to
ed87022
Compare
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 8
♻️ Duplicate comments (16)
src/platform/windows.rs (2)
3676-3695:⚠️ Potential issue | 🔴 Critical | 🏗️ Heavy liftThe elevated
.exelaunch is still path-based after verification.The verified copy is written under
std::env::temp_dir(), then launched by pathname withrun_uac(...). That means a same-user local process can race the gap between hash verification and the elevated open by swapping the temp file after verification but before the admin process consumes it. Move the verified bytes into a non-user-writable location before launch, or pass the expected hash into the elevated--updateflow and re-verify there.Also applies to: 3744-3755
3251-3255:⚠️ Potential issue | 🟠 Major | 🏗️ Heavy liftDon’t route every verified
.exethrough the single-file installer.
update_to_verified()hard-codes--single-exefor every.exe, andupdate_me_single_exe()then replaces the normal directoryXCOPYpath withcopy_single_exe_cmd(), which only installs the temp executable plus the broker. Any Windows release that ships sibling assets, DLLs, or helper binaries will land as a partial/mixed-version install. Gate this path behind metadata that proves the asset is truly standalone, or stage and verify the full payload directory before elevation.Also applies to: 3412-3416, 3691-3694
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/platform/windows.rs` around lines 3251 - 3255, The update flow currently forces every .exe through the single-file installer by hard-coding --single-exe in update_to_verified() and by having update_me_single_exe()/update_me_() always use copy_single_exe_cmd(), which breaks multi-file releases; change update_to_verified() to stop injecting --single-exe unconditionally and instead detect a validated "standalone" marker in the asset metadata (or an explicit payload manifest flag) and pass that boolean into update_me_(), then modify update_me_() to call copy_single_exe_cmd() only when single_exe is true and the metadata proves the asset is standalone; for non-standalone releases use the normal XCOPY/directory install path (the existing non-single-exe branch) or stage the complete payload to a temp dir and verify all files before elevating and swapping, reusing existing verification helpers so mixed-version installs cannot occur.src/core_main.rs (1)
79-88:⚠️ Potential issue | 🟠 Major | ⚡ Quick winFail closed on bare DMG updates.
parse_macos_update_args()still maps(None, None)toLegacyDmg, and the--updatedispatch still sends that branch toplatform::update_from_dmg(...). That leaves a default unsigned macOS offline-install path alive inside the verified-update flow, sorustdesk --update /path/RustDesk.dmgcan bypass sidecar verification entirely. Require--metadataand--signaturehere, or gate the legacy path behind an explicit unsafe flag instead of keeping it on the default CLI.Also applies to: 457-466
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/core_main.rs` around lines 79 - 88, parse_macos_update_args currently treats (None, None) as LegacyDmg which allows unsigned DMG updates to bypass verification; change parse_macos_update_args so that the match no longer maps (None, None) to MacosUpdateArgs::LegacyDmg by default and instead returns an Err requiring both --metadata and --signature, or only map (None, None) to LegacyDmg when an explicit unsafe flag (e.g., --allow-legacy-dmg) is provided; update the error message text to be descriptive and ensure callers that branch to platform::update_from_dmg must only be reached from the explicit Legacy/unsafe path (or removed), referencing the MacosUpdateArgs enum variants (VerifiedDmg, LegacyDmg), the parse_macos_update_args function, and the platform::update_from_dmg dispatch so the unsigned path is not on the default CLI.src/lang/sc.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winProvide translations or use English fallback for update verification UI.
Both localization keys are mapped to empty strings, which will result in blank UI text when Sardinian-locale users see the update verification flow. Users will not see any status message during update verification, degrading the user experience during a security-sensitive operation.
Consider either:
- Adding proper Sardinian translations for these strings, or
- Using English text as a fallback until translations are available
💬 Suggested fallback if translations are unavailable
- ("Verifying update", ""), - ("Please wait while {} verifies the update.", ""), + ("Verifying update", "Verifying update"), + ("Please wait while {} verifies the update.", "Please wait while {} verifies the update."),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/sc.rs` around lines 761 - 762, The two localization entries for the Sardinian locale— the key "Verifying update" and the key "Please wait while {} verifies the update." — are mapped to empty strings and must be populated; update the tuples in src/lang/sc.rs so they either contain proper Sardinian translations for those messages or, if translations are not available yet, set them to clear English fallback text (e.g., "Verifying update" and "Please wait while {} verifies the update.") to avoid blank UI during update verification.src/lang/sk.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winProvide translations or use English fallback for update verification UI.
Both localization keys are mapped to empty strings, which will result in blank UI text when Slovak-locale users see the update verification flow. Users will not see any status message during update verification, degrading the user experience during a security-sensitive operation.
Consider either:
- Adding proper Slovak translations for these strings, or
- Using English text as a fallback until translations are available
💬 Suggested fallback if translations are unavailable
- ("Verifying update", ""), - ("Please wait while {} verifies the update.", ""), + ("Verifying update", "Verifying update"), + ("Please wait while {} verifies the update.", "Please wait while {} verifies the update."),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/sk.rs` around lines 761 - 762, Two localization entries ("Verifying update", "") and ("Please wait while {} verifies the update.", "") are mapped to empty strings causing blank UI; replace the empty translation strings with proper Slovak translations (e.g., "Overenie aktualizácie" and "Počkajte, kým {} overí aktualizáciu.") or, if translations are not available, use the English fallbacks ("Verifying update" and "Please wait while {} verifies the update.") so the UI shows text during the update verification flow.src/lang/sl.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winProvide translations or use English fallback for update verification UI.
Both localization keys are mapped to empty strings, which will result in blank UI text when Slovenian-locale users see the update verification flow. Users will not see any status message during update verification, degrading the user experience during a security-sensitive operation.
Consider either:
- Adding proper Slovenian translations for these strings, or
- Using English text as a fallback until translations are available
💬 Suggested fallback if translations are unavailable
- ("Verifying update", ""), - ("Please wait while {} verifies the update.", ""), + ("Verifying update", "Verifying update"), + ("Please wait while {} verifies the update.", "Please wait while {} verifies the update."),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/sl.rs` around lines 761 - 762, The two Slovenian localization entries currently map "Verifying update" and "Please wait while {} verifies the update." to empty strings; replace those empty values with either proper Slovenian translations or an English fallback (e.g., "Verifying update" and "Please wait while {} verifies the update.") so the UI shows text during the update verification flow; update the corresponding entries for the keys "Verifying update" and "Please wait while {} verifies the update." in the Slovenian localization mapping (sl.rs) accordingly.src/lang/de.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winShared root cause: new verification locale entries are both empty and keyed with the wrong placeholder token.
The UI requestsVerifying updateandPlease wait while {$appName} verifies the update.; using empty values plus{}keys causes misses and blank/fallback rendering.
src/lang/de.rs#L761-L762: set non-empty values and change key toPlease wait while {$appName} verifies the update..src/lang/el.rs#L761-L762: set non-empty values and change key toPlease wait while {$appName} verifies the update..src/lang/eo.rs#L761-L762: set non-empty values and change key toPlease wait while {$appName} verifies the update..src/lang/es.rs#L761-L762: set non-empty values and change key toPlease wait while {$appName} verifies the update..src/lang/et.rs#L761-L762: set non-empty values and change key toPlease wait while {$appName} verifies the update..🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/de.rs` around lines 761 - 762, For each listed locale file, replace the two empty/incorrect entries so the message keys match the UI key "Please wait while {$appName} verifies the update." and provide non-empty localized strings: in src/lang/de.rs (761-762) change the key to "Please wait while {$appName} verifies the update." and set German translations for "Verifying update" and the full sentence (e.g., "Update wird überprüft" and a localized equivalent for "Please wait while {$appName} verifies the update."); do the same in src/lang/el.rs (761-762), src/lang/eo.rs (761-762), src/lang/es.rs (761-762), and src/lang/et.rs (761-762) — update the key to use {$appName} and supply appropriate non-empty localized strings for both entries in each file.src/lang/tw.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winFill in Traditional Chinese translations for update verification UI strings.
Both localization keys have empty string values, which will cause the update verification dialog to display blank status text. Users need informative feedback during the security-critical update verification process.
Provide Traditional Chinese translations for these keys before release (preserve the
{}placeholder exactly in the second string).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/tw.rs` around lines 761 - 762, Translate the two empty Traditional Chinese localization entries by replacing the empty strings for the keys "Verifying update" and "Please wait while {} verifies the update." with appropriate Traditional Chinese text (preserve the `{}` placeholder exactly in the second string); update the tuple entries in src/lang/tw.rs so the UI shows a meaningful status message during update verification.src/lang/tr.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winFill in Turkish translations for update verification UI strings.
Both localization keys have empty string values, which will cause the update verification dialog to display blank status text. Users need informative feedback during the security-critical update verification process.
Provide Turkish translations for these keys before release (preserve the
{}placeholder exactly in the second string).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/tr.rs` around lines 761 - 762, The two Turkish localization entries for the keys ("Verifying update", "") and ("Please wait while {} verifies the update.", "") are empty; replace them with proper Turkish translations (for example: "Güncelleme doğrulanıyor" for "Verifying update" and "Lütfen {} güncellemenin doğrulanmasını bekleyin." for the second), ensuring you preserve the {} placeholder exactly and update the string values in the same tuples (i.e., replace the empty "" with the Turkish text).src/lang/vi.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winEmpty translation strings will display blank UI text during update verification.
These placeholder entries will cause the update verification UI to show empty text instead of informative status messages. Users should see progress feedback during the security-critical update verification process.
Fill in Vietnamese translations before release to ensure users understand that verification is in progress.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/vi.rs` around lines 761 - 762, The two empty Vietnamese translation entries for the update verification messages need actual translated text: replace the empty string for the key "Verifying update" with an appropriate Vietnamese phrase (e.g., "Đang xác minh bản cập nhật") and replace the empty string for "Please wait while {} verifies the update." with a Vietnamese sentence that includes a placeholder for the verifier (e.g., "Vui lòng chờ trong khi {} đang xác minh bản cập nhật."). Ensure the placeholder {} remains intact and that both translations are complete, grammatically correct, and context-appropriate in src/lang/vi.rs.src/lang/uk.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winEmpty translation strings will display blank UI text during update verification.
These placeholder entries will cause the update verification UI to show empty text instead of informative status messages. Users should see progress feedback during the security-critical update verification process.
Fill in Ukrainian translations before release to ensure users understand that verification is in progress.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/uk.rs` around lines 761 - 762, Replace the empty Ukrainian translation values for the localization entries identified by the source strings "Verifying update" and "Please wait while {} verifies the update." with proper Ukrainian translations so the update verification UI shows informative status messages (i.e., supply the Ukrainian text as the second element of each tuple where currently ""). Ensure the second string preserves the "{}" placeholder exactly in the translated "Please wait..." entry.src/lang/pt_PT.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winEmpty Portuguese translations for update verification UI keys.
Lines 761-762 have empty values for the new update-verification keys, which will display blank text in the UI during update verification. This issue was already flagged in a previous review with suggested Portuguese translations.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/pt_PT.rs` around lines 761 - 762, Replace the two empty Portuguese translations for the update-verification UI keys: change ("Verifying update", "") to ("Verifying update", "A verificar actualização") and change ("Please wait while {} verifies the update.", "") to ("Please wait while {} verifies the update.", "Aguarde enquanto {} verifica a actualização.") so the UI shows the proper Portuguese text during update verification.src/lang/pl.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winEmpty Polish translations for update verification UI keys.
Lines 761-762 have empty values for the new update-verification keys, which will display blank text in the UI during update verification. This issue was already flagged in a previous review with suggested Polish translations.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/pl.rs` around lines 761 - 762, Two Polish translation entries are empty: replace the tuple ("Verifying update", "") with ("Verifying update", "Weryfikowanie aktualizacji") and replace ("Please wait while {} verifies the update.", "") with ("Please wait while {} verifies the update.", "Proszę czekać, trwa weryfikacja aktualizacji przez {}.") so the UI shows proper Polish text during update verification; update these exact entries in src/lang/pl.rs.src/updater.rs (2)
242-255:⚠️ Potential issue | 🟠 MajorHonor
update_msion non-Flutter Windows builds.This branch still hard-codes
"exe". On a non-Flutter MSI install, the updater resolves an EXE artifact but later enters the MSI install path, so artifact selection and installer handoff disagree.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/updater.rs` around lines 242 - 255, The function current_update_format currently ignores the update_msi parameter for the cfg branch all(target_os = "windows", not(feature = "flutter")); modify that branch so it mirrors the Flutter-Windows branch and returns "msi" when update_msi is true and "exe" otherwise (i.e., in current_update_format handle update_msi in the all(target_os = "windows", not(feature = "flutter")) block instead of returning the hard-coded "exe"); keep the non-Windows cfg that ignores update_msi as-is and remove or keep the existing unused-let only as needed to satisfy unused-parameter rules.
1049-1052:⚠️ Potential issue | 🟡 MinorRestore
VERIFIED_UPDATE_ARTIFACTSafter this test.This test clears and repopulates a process-global cache, then leaves that state behind for the rest of the test process. With parallel test execution, another test can observe the mutated cache and fail nondeterministically.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/updater.rs` around lines 1049 - 1052, The test verified_update_artifact_cache_rejects_mismatched_file_name_query mutates the global VERIFIED_UPDATE_ARTIFACTS and doesn't restore it; capture the current cache before clearing it and restore it at the end of the test to avoid leaking state. Concretely, at the start of the test clone the current contents (let original = VERIFIED_UPDATE_ARTIFACTS.lock().unwrap().clone()), then perform the clear and cache_verified_update_artifact(&artifact) calls as written, and finally restore the global with *VERIFIED_UPDATE_ARTIFACTS.lock().unwrap() = original; ensuring the restore runs before the test returns (or use an RAII guard if preferred). Ensure the symbols VERIFIED_UPDATE_ARTIFACTS, verified_update_artifact_cache_rejects_mismatched_file_name_query, cache_verified_update_artifact, and verified_artifact are used accordingly.src/common.rs (1)
1101-1128:⚠️ Potential issue | 🟠 MajorAdd hard timeouts to the version-check request path.
client.post(&url).json(&request).send().awaitandresponse.bytes().awaitare still unbounded here. If/version/lateststalls, the single update worker stays blocked insidecheck_update(), so later automatic and manual checks stop being serviced.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/common.rs` around lines 1101 - 1128, The version-check path currently awaits client.post(&url).json(&request).send().await and response.bytes().await with no bound; wrap both the HTTP send and the bytes read in hard timeouts (e.g., using tokio::time::timeout) inside the check_update flow so a stalled /version/latest cannot block the worker: apply a timeout when awaiting the first send() (the branch that produces latest_release_response via client.post(...).send().await and the retry branch that creates create_http_client_async(...).post(...).send().await) and also wrap the response.bytes().await call with a timeout; on timeout return an appropriate Err(anyhow!(...)) or convert the timeout error into the existing error handling path so the function fails fast and upsert_tls_cache is only called on successful, timely responses.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/flutter-build.yml:
- Around line 834-835: The workflow step in the publish-signed-update-metadata
job installs an unpinned cryptography package; change the step so it installs a
pinned dependency (e.g., replace `python -m pip install cryptography` with
`python -m pip install cryptography==<exact-version>` or `python -m pip install
-r requirements.txt`) and ensure the chosen exact-version or requirements file
is checked into the repo so the publish-signed-update-metadata job uses a
reproducible, audited cryptography release.
In `@flutter/lib/desktop/widgets/update_progress.dart`:
- Around line 56-60: Replace the hard-coded English message passed to
_showUpdateError (currently 'Failed to confirm downloader cancellation.') with a
localized string: add a new i18n key (e.g. update_cancel_confirm_failed) to the
app's localization files and use the localization accessor in this widget to
pass the localized value (for example,
AppLocalizations.of(context).updateCancelConfirmFailed) when calling
_showUpdateError(releasePageUrl, ..., showRetry: false); no other call sites
need change.
In `@libs/hbb_common`:
- Line 1: Initialize the missing submodule and pin it to the expected commit,
then inspect the signature verification implementation: run git submodule update
--init libs/hbb_common and ensure the checked-out commit matches
16bb58ae2c61be20faf9e5fb9696130cbba65e20; open the
update_metadata::verify_update_metadata function in that crate and confirm it
performs correct Ed25519 verification (using the proper public key, message
formatting, and ed25519 verification call) and that no unrelated changes were
introduced alongside it; if the commit differs, check out the pinned commit,
re-run tests/build, and if verify_update_metadata deviates from the known-good
logic, restore or adapt it to match correct Ed25519 verification semantics.
In `@res/generate_update_metadata.py`:
- Around line 149-177: command_sign must enforce the same stable-tag/version
consistency as the existing check-version command; add a validation step (reuse
the check-version logic if there is a helper like check_version_consistency or
replicate it in a new helper validate_stable_tag_version) inside command_sign
after you've built metadata and before writing/signing (i.e., before
write_stable_json(args.metadata_out, metadata) and
load_seed_from_env(args.private_key_seed_env)); if no shared helper exists,
implement validate_stable_tag_version(metadata or
args.package_id/args.version/args.published_at) and call it from command_sign so
signing fails on a stable tag/version mismatch the same way check-version does.
In `@src/hbbs_http/downloader.rs`:
- Around line 651-658: The cancel function currently removes finished downloader
entries, which makes a completed download appear as "cancelled"; in the cancel
function in src/hbbs_http/downloader.rs (function cancel, using DOWNLOADERS and
variable downloaders) stop removing finished entries — replace the branch that
checks get(id).is_some_and(|downloader| downloader.finished) so it simply
returns without calling downloaders.remove(id); leave removal to the existing
remove()/auto-delete logic and keep the rest of cancel behavior unchanged.
- Around line 70-97: The helper functions finish_download, fail_download, and
set_download_finalizing (and any per-chunk progress update sites) must be
guarded by the downloader's token so stale worker threads cannot mutate a
replaced entry: change their signatures to accept the worker token (same type as
the stored token), then inside each function lock DOWNLOADERS, lookup the entry
by id, and verify the stored entry.token == passed_token before doing any
mutations; if the token doesn't match, return early. Also apply the same token
check to the in-loop per-chunk get_mut(id) updates so progress updates are
skipped when the stored downloader no longer matches the worker token. Ensure
you only mutate downloader after the token equality check.
In `@src/lang/sq.rs`:
- Around line 761-762: For each locale file, replace the two empty-string
translation tuples for the keys ("Verifying update", "") and ("Please wait while
{} verifies the update.", "") with non-empty translations (or English fallbacks)
so the verification dialog is not blank: in src/lang/sq.rs (lines 761-762)
provide Albanian strings or English fallbacks for those two entries; in
src/lang/sr.rs (lines 761-762) provide Serbian strings or English fallbacks for
those two entries; and in src/lang/sv.rs (lines 761-762) provide Swedish strings
or English fallbacks for those two entries.
In `@src/lang/ta.rs`:
- Around line 761-762: Populate the two empty translation entries added for the
verified-update UI in both files so they are not empty: in src/lang/ta.rs (lines
761-762) replace the empty-string values for ("Verifying update", "") and
("Please wait while {} verifies the update.", "") with appropriate Tamil text
(or English as a temporary fallback) and ensure the second string preserves the
{} placeholder exactly; do the same change in src/lang/th.rs (lines 761-762)
replacing the empty values with proper Thai translations (or English fallback)
while keeping the {} placeholder intact.
---
Duplicate comments:
In `@src/common.rs`:
- Around line 1101-1128: The version-check path currently awaits
client.post(&url).json(&request).send().await and response.bytes().await with no
bound; wrap both the HTTP send and the bytes read in hard timeouts (e.g., using
tokio::time::timeout) inside the check_update flow so a stalled /version/latest
cannot block the worker: apply a timeout when awaiting the first send() (the
branch that produces latest_release_response via client.post(...).send().await
and the retry branch that creates
create_http_client_async(...).post(...).send().await) and also wrap the
response.bytes().await call with a timeout; on timeout return an appropriate
Err(anyhow!(...)) or convert the timeout error into the existing error handling
path so the function fails fast and upsert_tls_cache is only called on
successful, timely responses.
In `@src/core_main.rs`:
- Around line 79-88: parse_macos_update_args currently treats (None, None) as
LegacyDmg which allows unsigned DMG updates to bypass verification; change
parse_macos_update_args so that the match no longer maps (None, None) to
MacosUpdateArgs::LegacyDmg by default and instead returns an Err requiring both
--metadata and --signature, or only map (None, None) to LegacyDmg when an
explicit unsafe flag (e.g., --allow-legacy-dmg) is provided; update the error
message text to be descriptive and ensure callers that branch to
platform::update_from_dmg must only be reached from the explicit Legacy/unsafe
path (or removed), referencing the MacosUpdateArgs enum variants (VerifiedDmg,
LegacyDmg), the parse_macos_update_args function, and the
platform::update_from_dmg dispatch so the unsigned path is not on the default
CLI.
In `@src/lang/de.rs`:
- Around line 761-762: For each listed locale file, replace the two
empty/incorrect entries so the message keys match the UI key "Please wait while
{$appName} verifies the update." and provide non-empty localized strings: in
src/lang/de.rs (761-762) change the key to "Please wait while {$appName}
verifies the update." and set German translations for "Verifying update" and the
full sentence (e.g., "Update wird überprüft" and a localized equivalent for
"Please wait while {$appName} verifies the update."); do the same in
src/lang/el.rs (761-762), src/lang/eo.rs (761-762), src/lang/es.rs (761-762),
and src/lang/et.rs (761-762) — update the key to use {$appName} and supply
appropriate non-empty localized strings for both entries in each file.
In `@src/lang/pl.rs`:
- Around line 761-762: Two Polish translation entries are empty: replace the
tuple ("Verifying update", "") with ("Verifying update", "Weryfikowanie
aktualizacji") and replace ("Please wait while {} verifies the update.", "")
with ("Please wait while {} verifies the update.", "Proszę czekać, trwa
weryfikacja aktualizacji przez {}.") so the UI shows proper Polish text during
update verification; update these exact entries in src/lang/pl.rs.
In `@src/lang/pt_PT.rs`:
- Around line 761-762: Replace the two empty Portuguese translations for the
update-verification UI keys: change ("Verifying update", "") to ("Verifying
update", "A verificar actualização") and change ("Please wait while {} verifies
the update.", "") to ("Please wait while {} verifies the update.", "Aguarde
enquanto {} verifica a actualização.") so the UI shows the proper Portuguese
text during update verification.
In `@src/lang/sc.rs`:
- Around line 761-762: The two localization entries for the Sardinian locale—
the key "Verifying update" and the key "Please wait while {} verifies the
update." — are mapped to empty strings and must be populated; update the tuples
in src/lang/sc.rs so they either contain proper Sardinian translations for those
messages or, if translations are not available yet, set them to clear English
fallback text (e.g., "Verifying update" and "Please wait while {} verifies the
update.") to avoid blank UI during update verification.
In `@src/lang/sk.rs`:
- Around line 761-762: Two localization entries ("Verifying update", "") and
("Please wait while {} verifies the update.", "") are mapped to empty strings
causing blank UI; replace the empty translation strings with proper Slovak
translations (e.g., "Overenie aktualizácie" and "Počkajte, kým {} overí
aktualizáciu.") or, if translations are not available, use the English fallbacks
("Verifying update" and "Please wait while {} verifies the update.") so the UI
shows text during the update verification flow.
In `@src/lang/sl.rs`:
- Around line 761-762: The two Slovenian localization entries currently map
"Verifying update" and "Please wait while {} verifies the update." to empty
strings; replace those empty values with either proper Slovenian translations or
an English fallback (e.g., "Verifying update" and "Please wait while {} verifies
the update.") so the UI shows text during the update verification flow; update
the corresponding entries for the keys "Verifying update" and "Please wait while
{} verifies the update." in the Slovenian localization mapping (sl.rs)
accordingly.
In `@src/lang/tr.rs`:
- Around line 761-762: The two Turkish localization entries for the keys
("Verifying update", "") and ("Please wait while {} verifies the update.", "")
are empty; replace them with proper Turkish translations (for example:
"Güncelleme doğrulanıyor" for "Verifying update" and "Lütfen {} güncellemenin
doğrulanmasını bekleyin." for the second), ensuring you preserve the {}
placeholder exactly and update the string values in the same tuples (i.e.,
replace the empty "" with the Turkish text).
In `@src/lang/tw.rs`:
- Around line 761-762: Translate the two empty Traditional Chinese localization
entries by replacing the empty strings for the keys "Verifying update" and
"Please wait while {} verifies the update." with appropriate Traditional Chinese
text (preserve the `{}` placeholder exactly in the second string); update the
tuple entries in src/lang/tw.rs so the UI shows a meaningful status message
during update verification.
In `@src/lang/uk.rs`:
- Around line 761-762: Replace the empty Ukrainian translation values for the
localization entries identified by the source strings "Verifying update" and
"Please wait while {} verifies the update." with proper Ukrainian translations
so the update verification UI shows informative status messages (i.e., supply
the Ukrainian text as the second element of each tuple where currently "").
Ensure the second string preserves the "{}" placeholder exactly in the
translated "Please wait..." entry.
In `@src/lang/vi.rs`:
- Around line 761-762: The two empty Vietnamese translation entries for the
update verification messages need actual translated text: replace the empty
string for the key "Verifying update" with an appropriate Vietnamese phrase
(e.g., "Đang xác minh bản cập nhật") and replace the empty string for "Please
wait while {} verifies the update." with a Vietnamese sentence that includes a
placeholder for the verifier (e.g., "Vui lòng chờ trong khi {} đang xác minh bản
cập nhật."). Ensure the placeholder {} remains intact and that both translations
are complete, grammatically correct, and context-appropriate in src/lang/vi.rs.
In `@src/platform/windows.rs`:
- Around line 3251-3255: The update flow currently forces every .exe through the
single-file installer by hard-coding --single-exe in update_to_verified() and by
having update_me_single_exe()/update_me_() always use copy_single_exe_cmd(),
which breaks multi-file releases; change update_to_verified() to stop injecting
--single-exe unconditionally and instead detect a validated "standalone" marker
in the asset metadata (or an explicit payload manifest flag) and pass that
boolean into update_me_(), then modify update_me_() to call
copy_single_exe_cmd() only when single_exe is true and the metadata proves the
asset is standalone; for non-standalone releases use the normal XCOPY/directory
install path (the existing non-single-exe branch) or stage the complete payload
to a temp dir and verify all files before elevating and swapping, reusing
existing verification helpers so mixed-version installs cannot occur.
In `@src/updater.rs`:
- Around line 242-255: The function current_update_format currently ignores the
update_msi parameter for the cfg branch all(target_os = "windows", not(feature =
"flutter")); modify that branch so it mirrors the Flutter-Windows branch and
returns "msi" when update_msi is true and "exe" otherwise (i.e., in
current_update_format handle update_msi in the all(target_os = "windows",
not(feature = "flutter")) block instead of returning the hard-coded "exe"); keep
the non-Windows cfg that ignores update_msi as-is and remove or keep the
existing unused-let only as needed to satisfy unused-parameter rules.
- Around line 1049-1052: The test
verified_update_artifact_cache_rejects_mismatched_file_name_query mutates the
global VERIFIED_UPDATE_ARTIFACTS and doesn't restore it; capture the current
cache before clearing it and restore it at the end of the test to avoid leaking
state. Concretely, at the start of the test clone the current contents (let
original = VERIFIED_UPDATE_ARTIFACTS.lock().unwrap().clone()), then perform the
clear and cache_verified_update_artifact(&artifact) calls as written, and
finally restore the global with *VERIFIED_UPDATE_ARTIFACTS.lock().unwrap() =
original; ensuring the restore runs before the test returns (or use an RAII
guard if preferred). Ensure the symbols VERIFIED_UPDATE_ARTIFACTS,
verified_update_artifact_cache_rejects_mismatched_file_name_query,
cache_verified_update_artifact, and verified_artifact are used accordingly.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: abcab0cd-7491-45e3-a9fd-c26691cae867
📒 Files selected for processing (67)
.github/workflows/flutter-build.yml.github/workflows/flutter-tag.ymlflutter/lib/desktop/widgets/update_cancel_controller.dartflutter/lib/desktop/widgets/update_progress.dartlibs/hbb_commonres/generate_update_metadata.pyres/test_generate_update_metadata.pysrc/common.rssrc/core_main.rssrc/flutter_ffi.rssrc/hbbs_http.rssrc/hbbs_http/downloader.rssrc/hbbs_http/http_client.rssrc/lang/ar.rssrc/lang/be.rssrc/lang/bg.rssrc/lang/ca.rssrc/lang/cn.rssrc/lang/cs.rssrc/lang/da.rssrc/lang/de.rssrc/lang/el.rssrc/lang/eo.rssrc/lang/es.rssrc/lang/et.rssrc/lang/eu.rssrc/lang/fa.rssrc/lang/fi.rssrc/lang/fr.rssrc/lang/ge.rssrc/lang/gu.rssrc/lang/he.rssrc/lang/hi.rssrc/lang/hr.rssrc/lang/hu.rssrc/lang/id.rssrc/lang/it.rssrc/lang/ja.rssrc/lang/ko.rssrc/lang/kz.rssrc/lang/lt.rssrc/lang/lv.rssrc/lang/ml.rssrc/lang/nb.rssrc/lang/nl.rssrc/lang/pl.rssrc/lang/pt_PT.rssrc/lang/ptbr.rssrc/lang/ro.rssrc/lang/ru.rssrc/lang/sc.rssrc/lang/sk.rssrc/lang/sl.rssrc/lang/sq.rssrc/lang/sr.rssrc/lang/sv.rssrc/lang/ta.rssrc/lang/template.rssrc/lang/th.rssrc/lang/tr.rssrc/lang/tw.rssrc/lang/uk.rssrc/lang/vi.rssrc/platform/macos.rssrc/platform/privileges_scripts/update.scptsrc/platform/windows.rssrc/updater.rs
ed87022 to
e06f871
Compare
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (29)
res/generate_update_metadata.py (1)
18-18:⚠️ Potential issue | 🟠 Major | 🏗️ Heavy liftThe verified-update pipeline is still hardwired to upstream release assets. The CLI parser/verifier, the publishing workflow, and the tests all assume
https://github.com/rustdesk/rustdesk/releases/download/..., so signed metadata generated by this PR cannot correctly target the repository that actually published the release assets.
res/generate_update_metadata.py#L18-L18: replace the hardcodedGITHUB_RELEASE_PREFIXwith a runtime release-base/repo input rather than baking inrustdesk/rustdesk.res/generate_update_metadata.py#L66-L92: makeparse_artifact_url()andexpected_artifact_url()validate/build URLs against that supplied release base instead of the fixed upstream path.res/generate_update_metadata.py#L215-L246: thread the same release-base input intocommand_verify()so verification checks artifact URLs against the publishing repo, not upstream..github/workflows/flutter-build.yml#L891-L901: pass${{ github.server_url }}/${{ github.repository }}/releases/download/${TAG_NAME}/...(or the new CLI release-base argument) when generating fragments.res/test_generate_update_metadata.py#L12-L13: stop hardcoding the upstream release base in the test fixture constant.res/test_generate_update_metadata.py#L69-L70: build fragment URLs from the same configurable release-base input so the tests cover the repository that published the assets.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@res/generate_update_metadata.py` at line 18, Replace the hardcoded GITHUB_RELEASE_PREFIX constant in res/generate_update_metadata.py (18-18) with a runtime-configurable release-base input (e.g., a new parameter or CLI arg) and use that variable everywhere; update parse_artifact_url() and expected_artifact_url() in res/generate_update_metadata.py (66-92) to validate/build URLs against this injected release-base instead of the fixed upstream path; thread the same release-base parameter into command_verify() in res/generate_update_metadata.py (215-246) so verification checks use the publishing repo; update the GitHub Actions step in .github/workflows/flutter-build.yml (891-901) to pass the runtime release-base (for example ${ { github.server_url } }/${ { github.repository } }/releases/download/${TAG_NAME}/...) or the new CLI argument when generating fragments; and change the test fixture and fragment construction in res/test_generate_update_metadata.py (12-13 and 69-70) to derive the expected release-base from the configurable input instead of hardcoding the upstream release URL so tests exercise the new behavior..github/workflows/flutter-build.yml (2)
837-841:⚠️ Potential issue | 🟠 Major | 🏗️ Heavy liftRun the Rust-side verifier here, not just
cargo check.This job generates and signs
rustdesk-update.json, but the only consumer exercised in CI is the Python verifier that produced it.cargo check -p hbb_common --lib --no-default-featuresproves the Rust code compiles; it does not catch schema or validation drift betweenres/generate_update_metadata.pyand the actual Rust updater path that will consume this metadata at runtime.#!/bin/bash set -euo pipefail echo "== Locate hbb_common verifier entrypoints ==" fd -HI . libs/hbb_common 2>/dev/null || true rg -n --hidden -S "update metadata|rustdesk-update|verify.*metadata|ed25519|signature" libs/hbb_common src 2>/dev/null || true rg -n --hidden -S '^\s*\[\[bin\]\]|^\s*name\s*=' libs/hbb_common/Cargo.toml 2>/dev/null || true🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/flutter-build.yml around lines 837 - 841, The CI currently only runs "cargo check -p hbb_common --lib --no-default-features", which only compiles hbb_common; replace or augment that step to execute the Rust metadata verifier binary from the hbb_common crate (the binary that validates/sig-checks rustdesk-update.json) so the generated res/rustdesk-update.json is actually validated by the Rust code used at runtime; locate the verifier binary in the hbb_common crate (e.g., via Cargo.toml bin entries) and run it with cargo run --package hbb_common --bin <verifier-bin-name> --no-default-features -- <path-to/generated/rustdesk-update.json> (or equivalent invocation) so the job fails on verification errors, ensuring the workflow runs the Rust verifier rather than only doing cargo check.
834-835:⚠️ Potential issue | 🟠 Major | ⚡ Quick winPin
cryptographyfor reproducible metadata signing.
python -m pip install cryptographystill pulls whatever happens to be latest on PyPI, so this signing job is not reproducible and can drift independently of the tested version. Please install an exact version or a checked-in pinned requirements file here as well.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/flutter-build.yml around lines 834 - 835, The workflow step named "Install Python dependencies" currently runs an unpinned pip install for cryptography which makes signing non-reproducible; update that step in .github/workflows/flutter-build.yml to install a pinned cryptography version (use an exact version specifier) or change it to install from a checked-in, pinned requirements file so the metadata signing environment is deterministic.Source: Linters/SAST tools
.github/workflows/flutter-tag.yml (1)
17-19:⚠️ Potential issue | 🟠 Major | ⚡ Quick winDon't force verified-metadata publishing for every tag build.
publish-update-metadata: truemakes every tag invocation take the signed-metadata path, butflutter-build.ymlonly succeeds on repositories that also have the Ed25519 signing material and all signed platform artifacts available. On forks or repos without that setup, this flips tagged releases from the legacy publish path into a failing metadata job instead of cleanly opting out. Please make this an explicit dispatch input or gate it on repository/secret readiness before passingtruethrough.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/flutter-tag.yml around lines 17 - 19, The workflow currently forces publish-update-metadata: true for tag builds which breaks forks/no-signing repos; change the literal true into a gated value controlled by an explicit dispatch input or a readiness check: add a workflow_dispatch input (e.g., inputs.publish_update_metadata, default: false) and replace publish-update-metadata: true with the expression that reads that input (e.g., publish-update-metadata: ${{ inputs.publish_update_metadata }}), or alternatively set it conditionally based on the presence of signing secrets (e.g., publish-update-metadata: ${{ secrets.ED25519_PRIVATE_KEY && secrets.SIGNED_ARTIFACTS_AVAILABLE }}); ensure any callers that need metadata publishing opt-in via the new input or that the gating uses secret existence checks before enabling publish-update-metadata.src/updater.rs (1)
242-255:⚠️ Potential issue | 🟠 Major | ⚡ Quick winHonor
update_msion non-Flutter Windows too.
check_update()still computesupdate_msifor every Windows build, andupdate_new_version()still sendsupdate_msi == trueintoupdate_me_msi(). This helper hard-codes"exe"under#[cfg(all(target_os = "windows", not(feature = "flutter")))], so an MSI install on that target resolves an EXE artifact and then hands the EXE to the MSI installer path. The regression test at Lines 915-917 currently locks that wrong behavior in.Suggested fix
pub(crate) fn current_update_format(update_msi: bool) -> &'static str { - #[cfg(any(not(target_os = "windows"), all(target_os = "windows", not(feature = "flutter"))))] + #[cfg(not(target_os = "windows"))] let _ = update_msi; #[cfg(all(target_os = "windows", feature = "flutter"))] { if update_msi { return "msi"; @@ } #[cfg(all(target_os = "windows", not(feature = "flutter")))] { - "exe" + if update_msi { + "msi" + } else { + "exe" + } }#[cfg(all(target_os = "windows", not(feature = "flutter")))] #[test] fn current_update_format_uses_exe_for_non_flutter_windows() { - assert_eq!(current_update_format(true), "exe"); + assert_eq!(current_update_format(true), "msi"); assert_eq!(current_update_format(false), "exe"); }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/updater.rs` around lines 242 - 255, The function current_update_format incorrectly hard-codes "exe" for Windows builds without the flutter feature; update it so the all(target_os = "windows", not(feature = "flutter")) cfg block respects the update_msi parameter like the flutter branch does: in current_update_format, remove the unconditional "exe" return and add a conditional that returns "msi" when update_msi is true and "exe" otherwise (matching the behavior used by check_update()/update_new_version()/update_me_msi()).src/core_main.rs (1)
79-88:⚠️ Potential issue | 🟠 Major | ⚡ Quick winDrop the unsigned
LegacyDmgfallback.The
(None, None)arm still accepts--update <dmg>without--metadata/--signature, and the macOS dispatcher later routes that case toplatform::update_from_dmg(). That keeps an unverified offline-update path alive, which undercuts this PR’s signed-metadata contract for macOS DMG installs.🔐 Minimal direction
- (None, None) => Ok(MacosUpdateArgs::LegacyDmg { - dmg_path: dmg_path.clone(), - }), + (None, None) => Err( + "signed metadata is required for DMG updates; pass --metadata and --signature" + .to_owned(), + ),Please also remove the now-dead
LegacyDmgenum/dispatch/test branches once this parser arm is gone.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/core_main.rs` around lines 79 - 88, Replace the permissive (None, None) match arm so the parser never returns MacosUpdateArgs::LegacyDmg: change the match in the args parsing to only accept (Some(metadata_path), Some(signature_path)) and return Err(...) for any other combination (i.e., require both metadata and signature); then remove the MacosUpdateArgs::LegacyDmg enum variant and all code paths that dispatched to it (including calls that routed unverified updates to platform::update_from_dmg()), and delete or update tests that expected the legacy/unsigned DMG flow so they assert the parser now errors instead.src/platform/windows.rs (2)
3691-3694:⚠️ Potential issue | 🟠 Major | 🏗️ Heavy liftDon’t route every verified
.exethrough the single-file installer.
update_to_verified()always passes--single-exe, butupdate_me_(..., true)only copies the verified.exeplus the broker binary. Any sibling payload that the normal directory-copy path would update is skipped, so.exereleases can land as mixed-version installs. GateUPDATE_SINGLE_EXE_ARGon metadata that proves the artifact is truly standalone; otherwise keep the full-directory update path.
2088-2092:⚠️ Potential issue | 🟠 Major | 🏗️ Heavy liftUse parse/verification success here, not the “is custom client” flag.
read_custom_client()is being treated as a validity check, but this branch only has a boolean that answers whether the payload turns the build into a custom client. A stagedcustom.txtthat parses successfully yet keeps the default app name will still hit Line 2091 and abort the update path as “invalid”. Split “verified/parses” from “is custom client” before rejecting the staged file.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/platform/windows.rs` around lines 2088 - 2092, The code treats the boolean from crate::read_custom_client(...) as a validity check; instead first attempt to parse/verify the staged file and only use the "is custom client" flag afterwards. Change the logic around custom_client_config/custom_txt_path so you call a parsing/verification routine (either change read_custom_client to return Result/tuple like (parsed, is_custom) or add a new crate::verify_or_parse_custom_client that returns a parse result or error), check parse success on custom_client_config.trim() and only abort the update path if parsing/verification fails; use the separate is_custom_client flag only to decide whether to apply custom-client behavior, not to mark the file invalid. Ensure the identifiers referenced include custom_client_config, custom_txt_path, and read_custom_client (or the new verify/parse function) so reviewers can find and update the branch correctly.src/platform/macos.rs (1)
1211-1218:⚠️ Potential issue | 🟠 Major | ⚡ Quick winDerive the sidecar verification policy from the active client identity.
verify_dmg_sidecar_metadata()already derives the query from the current DMG name/arch, but this helper still pinsappandallowed_package_idsto"rustdesk". Everywhere else in this file the macOS install flow is branding-aware (crate::get_app_name(),get_bundle_id()), so branded/custom clients will reject otherwise valid signed metadata here.Build the policy from the same runtime app/package identifiers the shared updater path uses, and keep those derived strings alive in the same scope as
verify_update_metadata()so the borrowedUpdateMetadataPolicyfields remain valid.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/platform/macos.rs` around lines 1211 - 1218, The helper dmg_sidecar_policy() currently hardcodes app and allowed_package_ids to "rustdesk"; change it so the policy is constructed from the runtime identity strings used elsewhere (e.g. crate::get_app_name() and get_bundle_id()) and ensure those derived String values live in the same scope as the call to verify_update_metadata()/verify_dmg_sidecar_metadata so the returned UpdateMetadataPolicy borrows valid data; practically, either make dmg_sidecar_policy accept &str parameters (app_name and package_id) or move the policy construction into the caller that already obtains the app name and bundle id so you pass references to those local Strings into UpdateMetadataPolicy rather than using a hardcoded literal.src/lang/be.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winPopulate the new Belarusian verification-copy entries.
These two keys still map to empty strings, so the verification dialog shows blank text in Belarusian. Keep
{}exactly as-is in the second value.♻️ Minimal fix
- ("Verifying update", ""), - ("Please wait while {} verifies the update.", ""), + ("Verifying update", "Праверка абнаўлення"), + ("Please wait while {} verifies the update.", "Калі ласка, пачакайце, пакуль {} правярае абнаўленне."),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/be.rs` around lines 761 - 762, Replace the two empty Belarusian strings for the keys "Verifying update" and "Please wait while {} verifies the update." in src/lang/be.rs with their proper Belarusian translations; keep the placeholder {} exactly as-is in the second translation and ensure the translated text uses the same surrounding punctuation and capitalization as the original keys so the UI displays correctly.src/lang/ar.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winPopulate the new Arabic verification-copy entries.
Both values are still empty, so the new verification dialog renders blank text in Arabic. Keep
{}exactly as-is in the second string.♻️ Minimal fix
- ("Verifying update", ""), - ("Please wait while {} verifies the update.", ""), + ("Verifying update", "جارٍ التحقق من التحديث"), + ("Please wait while {} verifies the update.", "يرجى الانتظار بينما يتحقق {} من التحديث."),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/ar.rs` around lines 761 - 762, Populate the two Arabic translation entries for the keys "Verifying update" and "Please wait while {} verifies the update." by replacing the empty strings with appropriate Arabic text (keeping the placeholder {} exactly as-is in the second string), i.e., provide a short Arabic translation for "Verifying update" and a sentence for "Please wait while {} verifies the update." that preserves the {} placeholder.flutter/lib/desktop/widgets/update_progress.dart (1)
167-169:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winUse the existing localized button labels in the update error dialog.
Download,Retry, andClosealready exist in the locale tables, but this dialog bypasses them and renders English-only buttons in non-English locales.♻️ Minimal fix
- dialogButton('Download', onPressed: jumplink), - if (showRetry) dialogButton('Retry', onPressed: retry), - dialogButton('Close', onPressed: close), + dialogButton(translate('Download'), onPressed: jumplink), + if (showRetry) dialogButton(translate('Retry'), onPressed: retry), + dialogButton(translate('Close'), onPressed: close),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@flutter/lib/desktop/widgets/update_progress.dart` around lines 167 - 169, Replace the hard-coded English labels in the update error dialog's dialogButton calls with the localized labels from the app's locale tables (use the existing localization getters, e.g. l10n.download / l10n.retry / l10n.close or AppLocalizations.*). Update the three calls that use 'Download', 'Retry', and 'Close' in update_progress.dart (the dialogButton(...) calls that reference jumplink, retry, close and the showRetry condition) to pass the localized strings; if dialogButton does not accept BuildContext or a localized string, adjust its signature or call site so it receives the localized text (and import the localization helper where needed). Ensure no other behavior changes.src/lang/ptbr.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winFill the update-verification strings or add an explicit fallback.
These entries are still empty in all three locales, so the verification UI will render blank text. Replace them with translations or route empty values through English defaults.
src/lang/ptbr.rs#L761-L762: add pt-BR translations or fallback handling.src/lang/ro.rs#L761-L762: add Romanian translations or fallback handling.src/lang/ru.rs#L761-L762: add Russian translations or fallback handling.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/ptbr.rs` around lines 761 - 762, The two localization entries currently left empty — ("Verifying update", "") and ("Please wait while {} verifies the update.", "") — must be populated or fallback to English; update each affected file: in src/lang/ptbr.rs (lines 761-762) provide Portuguese (pt-BR) translations for "Verifying update" and "Please wait while {} verifies the update." or call the existing fallback helper so the English strings are used, in src/lang/ro.rs (lines 761-762) provide Romanian translations or wire these entries to the English defaults, and in src/lang/ru.rs (lines 761-762) provide Russian translations or route them through the English fallback; ensure the translated strings keep the "{}" placeholder intact for the second message.src/lang/bg.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winRoot cause: new update-verification locale keys were added with empty values in multiple language maps. This leaves the verification UX blank in affected locales.
src/lang/bg.rs#L761-L762: provide non-empty Bulgarian translations; keep{}unchanged in the second string.src/lang/ca.rs#L761-L762: provide non-empty Catalan translations; keep{}unchanged in the second string.src/lang/cs.rs#L761-L762: provide non-empty Czech translations; keep{}unchanged in the second string.src/lang/da.rs#L761-L762: provide non-empty Danish translations; keep{}unchanged in the second string.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/bg.rs` around lines 761 - 762, Provide non-empty translations for the two new locale keys ("Verifying update" and "Please wait while {} verifies the update.") in each affected file: in src/lang/bg.rs (lines 761-762) add Bulgarian text for both strings, preserving the {} placeholder in the second string; in src/lang/ca.rs (lines 761-762) add Catalan text for both strings, preserving {}; in src/lang/cs.rs (lines 761-762) add Czech text for both strings, preserving {}; and in src/lang/da.rs (lines 761-762) add Danish text for both strings, preserving {}. Ensure the translations replace the current empty strings and keep the placeholder exactly as "{}" in the second entry.src/lang/sc.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winProvide translations or use English fallback for update verification UI.
Both localization keys are mapped to empty strings, which will result in blank UI text when Sardinian-locale users see the update verification flow. This degrades the user experience during a security-sensitive operation.
💬 Suggested fallback if translations are unavailable
- ("Verifying update", ""), - ("Please wait while {} verifies the update.", ""), + ("Verifying update", "Verifying update"), + ("Please wait while {} verifies the update.", "Please wait while {} verifies the update."),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/sc.rs` around lines 761 - 762, The two Sardinian localization entries ("Verifying update", "") and ("Please wait while {} verifies the update.", "") are empty and will render blank text; replace the empty strings with proper Sardinian translations or, if translations are unavailable, set them to English fallback strings ("Verifying update" and "Please wait while {} verifies the update.") so the update verification UI shows meaningful text; update the tuple entries in the localization mapping where those keys appear (the two tuples shown) to contain the translated or fallback strings.src/lang/sk.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winProvide translations or use English fallback for update verification UI.
Both localization keys are mapped to empty strings, which will result in blank UI text when Slovak-locale users see the update verification flow. This degrades the user experience during a security-sensitive operation.
💬 Suggested fallback if translations are unavailable
- ("Verifying update", ""), - ("Please wait while {} verifies the update.", ""), + ("Verifying update", "Verifying update"), + ("Please wait while {} verifies the update.", "Please wait while {} verifies the update."),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/sk.rs` around lines 761 - 762, The two Slovak localization entries for the update verification UI—specifically the key strings "Verifying update" and "Please wait while {} verifies the update."—are mapped to empty strings; fill them with appropriate Slovak translations or, if translations are not available, set them to English fallback text (e.g., "Verifying update" and "Please wait while {} verifies the update.") to avoid blank UI; update the tuple values in the localization mapping where those exact keys appear so the update verification flow displays non-empty text.src/lang/sl.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winProvide translations or use English fallback for update verification UI.
Both localization keys are mapped to empty strings, which will result in blank UI text when Slovenian-locale users see the update verification flow. This degrades the user experience during a security-sensitive operation.
💬 Suggested fallback if translations are unavailable
- ("Verifying update", ""), - ("Please wait while {} verifies the update.", ""), + ("Verifying update", "Verifying update"), + ("Please wait while {} verifies the update.", "Please wait while {} verifies the update."),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/sl.rs` around lines 761 - 762, Two localization entries are mapped to empty strings causing blank UI: update the tuple for the key "Verifying update" and the key "Please wait while {} verifies the update." to either proper Slovenian translations or an English fallback; specifically replace the "" values with the appropriate translated strings (e.g. "Preverjanje posodobitve" and "Počakajte, medtem ko {} preverja posodobitev.") or the English phrases if translations aren’t available so the verification UI shows readable text.src/lang/de.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winPopulate the new verification locale values instead of leaving them empty.
The same i18n gap appears across all listed files: the newly added verification strings are present but mapped to
"", so these locales won’t provide localized text for this flow.
src/lang/de.rs#L761-L762: add non-empty German translations for both new keys.src/lang/el.rs#L761-L762: add non-empty Greek translations for both new keys.src/lang/eo.rs#L761-L762: add non-empty Esperanto translations for both new keys.src/lang/es.rs#L761-L762: add non-empty Spanish translations for both new keys.src/lang/et.rs#L761-L762: add non-empty Estonian translations for both new keys.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/de.rs` around lines 761 - 762, Populate the two empty locale values for the "Verifying update" and "Please wait while {} verifies the update." keys by replacing the empty strings with proper translations: in src/lang/de.rs (lines 761-762) set German translations ("Aktualisierung wird überprüft", "Bitte warten, während {} das Update überprüft."); in src/lang/el.rs (lines 761-762) set Greek translations ("Επαλήθευση ενημέρωσης", "Παρακαλώ περιμένετε ενώ {} επαληθεύει την ενημέρωση."); in src/lang/eo.rs (lines 761-762) set Esperanto translations ("Verifiko de ĝisdatigo", "Bonvolu atendi dum {} verificas la ĝisdatigon."); in src/lang/es.rs (lines 761-762) set Spanish translations ("Verificando actualización", "Espere mientras {} verifica la actualización."); and in src/lang/et.rs (lines 761-762) set Estonian translations ("Värskenduse kontrollimine", "Palun oodake, kuni {} kontrollib värskendust.").src/lang/fi.rs (1)
762-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAlign placeholder with the runtime key format.
Line 762 still uses
{}; it should be{$appName}so this key is resolved at runtime.Suggested fix
- ("Please wait while {} verifies the update.", ""), + ("Please wait while {$appName} verifies the update.", ""),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/fi.rs` at line 762, The translation entry containing "Please wait while {} verifies the update." should use the runtime placeholder format; replace the "{}" with "{$appName}" so the tuple becomes ("Please wait while {$appName} verifies the update.", ""), updating that string literal in src/lang/fi.rs to align with the runtime key format used by the app.src/lang/ge.rs (1)
762-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winUse the exact placeholder token expected by update dialog lookup.
Line 762 still uses
{}; this should be{$appName}for runtime key matching.Suggested fix
- ("Please wait while {} verifies the update.", ""), + ("Please wait while {$appName} verifies the update.", ""),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/ge.rs` at line 762, The translation entry ("Please wait while {} verifies the update.", "") uses the wrong placeholder token; replace the `{}` placeholder with the exact token `{$appName}` so the update dialog lookup matches at runtime (i.e., change the first element of that tuple from "Please wait while {} verifies the update." to "Please wait while {$appName} verifies the update.").src/lang/fa.rs (1)
762-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winFix key placeholder to match runtime string interpolation key.
Line 762 should use
{$appName}instead of{}to match runtime translation lookup.Suggested fix
- ("Please wait while {} verifies the update.", ""), + ("Please wait while {$appName} verifies the update.", ""),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/fa.rs` at line 762, Update the translation key that currently reads ("Please wait while {} verifies the update.", "") to use the runtime interpolation name: replace the {} placeholder with {$appName} so it becomes ("Please wait while {$appName} verifies the update.", ""); this ensures the translation lookup matches the runtime string interpolation key.src/lang/eu.rs (1)
762-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winUse the runtime placeholder token expected by lookup.
Line 762 still uses
{}in the key, which won’t match the runtime lookup string that uses{$appName}.Suggested fix
- ("Please wait while {} verifies the update.", ""), + ("Please wait while {$appName} verifies the update.", ""),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/eu.rs` at line 762, The translation entry key currently uses the placeholder "{}" which doesn't match the runtime lookup token; update the key string ("Please wait while {} verifies the update.") to use the runtime placeholder "{$appName}" so it reads "Please wait while {$appName} verifies the update." (leave the value side as-is).src/lang/fr.rs (1)
762-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winReplace positional placeholder with named placeholder used by runtime.
Line 762 should use
{$appName}instead of{}to avoid key mismatch during lookup.Suggested fix
- ("Please wait while {} verifies the update.", ""), + ("Please wait while {$appName} verifies the update.", ""),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/fr.rs` at line 762, Update the positional placeholder in the translation entry ("Please wait while {} verifies the update.", "") to use the runtime's named placeholder {$appName} instead of {} so the key matches the lookup; locate the tuple containing the string "Please wait while {} verifies the update." and replace {} with {$appName}.src/lang/ta.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winPopulate the new locale strings in both files.
The shared root cause is that the verified-update labels are still empty in both locales, so those users see fallback text instead of translated strings.
src/lang/ta.rs#L761-L762: add Tamil translations for both entries; preserve the{}placeholder in the second string.src/lang/th.rs#L761-L762: add Thai translations for both entries; preserve the{}placeholder in the second string.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/ta.rs` around lines 761 - 762, For each affected locale file, replace the empty verified-update label tuples at the specified ranges with translated Tamil and Thai text respectively, preserving the "{}" placeholder in the second string: in src/lang/ta.rs (lines 761-762) populate the first tuple with the Tamil translation for "Verifying update" and the second tuple with the Tamil translation for "Please wait while {} verifies the update." (keep the {} unchanged); in src/lang/th.rs (lines 761-762) populate the first tuple with the Thai translation for "Verifying update" and the second tuple with the Thai translation for "Please wait while {} verifies the update." (again preserving the {} placeholder).src/lang/tw.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winEmpty translation strings will display blank UI text during update verification.
These placeholder entries will cause the update verification UI to show empty text instead of informative status messages. Users should see progress feedback during the security-critical update verification process.
Fill in Traditional Chinese translations before release to ensure users understand that verification is in progress.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/tw.rs` around lines 761 - 762, Replace the two empty Traditional Chinese translation entries for the localization keys "Verifying update" and "Please wait while {} verifies the update." in src/lang/tw.rs with appropriate Traditional Chinese strings so the update verification UI shows readable status and progress messages (update the mapping values for those exact keys).src/lang/id.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winFill new update-verification locale entries instead of leaving empty values.
At Line 761 and Line 762 across these locale files, both newly added verification keys map to
"". This leaves the new flow without localized copy in these languages.
src/lang/id.rs#L761-L762: provide Indonesian values for both keys, preserving{}in the second string.src/lang/it.rs#L761-L762: provide Italian values for both keys, preserving{}in the second string.src/lang/ja.rs#L761-L762: provide Japanese values for both keys, preserving{}in the second string.src/lang/ko.rs#L761-L762: provide Korean values for both keys, preserving{}in the second string.src/lang/kz.rs#L761-L762: provide Kazakh values for both keys, preserving{}in the second string.src/lang/uk.rs#L761-L762: provide Ukrainian values for both keys, preserving{}in the second string.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/id.rs` around lines 761 - 762, Fill the two empty locale entries at each listed site with the translated strings (preserve the {} placeholder exactly). For src/lang/id.rs (761-762) set "Verifying update" => "Memverifikasi pembaruan" and "Please wait while {} verifies the update." => "Harap tunggu sementara {} memverifikasi pembaruan."; for src/lang/it.rs (761-762) set "Verifying update" => "Verifica aggiornamento" and "Please wait while {} verifies the update." => "Attendere mentre {} verifica l'aggiornamento."; for src/lang/ja.rs (761-762) set "Verifying update" => "更新を確認しています" and "Please wait while {} verifies the update." => "{} が更新を確認している間、お待ちください。"; for src/lang/ko.rs (761-762) set "Verifying update" => "업데이트 확인 중" and "Please wait while {} verifies the update." => "{}가 업데이트를 확인하는 동안 기다려 주세요."; for src/lang/kz.rs (761-762) set "Verifying update" => "Жаңартуды тексеру" and "Please wait while {} verifies the update." => "{} жаңартуды тексеріп жатқанда күтіңіз."; for src/lang/uk.rs (761-762) set "Verifying update" => "Перевірка оновлення" and "Please wait while {} verifies the update." => "Будь ласка, зачекайте, поки {} перевіряє оновлення."src/lang/vi.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winFill in the Vietnamese update-verification strings.
These entries are still empty, so the update-check UI will render blank status text during verification. Please provide translations for both strings.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/vi.rs` around lines 761 - 762, Replace the two empty Vietnamese strings for the update-verification messages: for the English "Verifying update" set the Vietnamese text to "Đang xác minh bản cập nhật", and for "Please wait while {} verifies the update." set it to "Vui lòng chờ trong khi {} xác minh bản cập nhật." Update the corresponding tuple entries in src/lang/vi.rs so the second element of ("Verifying update", "") and ("Please wait while {} verifies the update.", "") contain these Vietnamese translations.src/lang/pl.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAdd Polish translations for update verification messages.
The empty translation values will result in blank UI text during the update verification flow, degrading the user experience. A past review already identified this issue and provided suggested translations.
Suggested Polish translations (from past review)
- ("Verifying update", ""), - ("Please wait while {} verifies the update.", ""), + ("Verifying update", "Trwa weryfikacja aktualizacji"), + ("Please wait while {} verifies the update.", "Proszę czekać, {} weryfikuje aktualizację."),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/pl.rs` around lines 761 - 762, Replace the empty Polish translation values for the two message keys in the tuple entries ("Verifying update", "") and ("Please wait while {} verifies the update.", "") with the correct Polish strings: set "Verifying update" → "Weryfikacja aktualizacji" and set "Please wait while {} verifies the update." → "Proszę czekać, trwa weryfikacja aktualizacji przez {}." so the update verification UI displays proper Polish text.src/lang/pt_PT.rs (1)
761-762:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAdd Portuguese (pt-PT) translations for update verification messages.
The empty translation values will result in blank UI text during the update verification flow, degrading the user experience. A past review already identified this issue and provided suggested translations.
Suggested Portuguese translations (from past review)
- ("Verifying update", ""), - ("Please wait while {} verifies the update.", ""), + ("Verifying update", "A verificar atualização"), + ("Please wait while {} verifies the update.", "Aguarde enquanto o {} verifica a atualização."),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/lang/pt_PT.rs` around lines 761 - 762, The two Portuguese translations for the update-verification messages are empty; update the tuple entries for "Verifying update" and "Please wait while {} verifies the update." so they contain Portuguese text (e.g. "A verificar a atualização" and "Aguarde enquanto {} verifica a atualização."). Modify the corresponding entries in src/lang/pt_PT.rs to replace the "" values with these translations so the UI shows proper Portuguese during update verification.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 56f6353c-902b-4dac-8302-cffe0a6ae796
📒 Files selected for processing (67)
.github/workflows/flutter-build.yml.github/workflows/flutter-tag.ymlflutter/lib/desktop/widgets/update_cancel_controller.dartflutter/lib/desktop/widgets/update_progress.dartlibs/hbb_commonres/generate_update_metadata.pyres/test_generate_update_metadata.pysrc/common.rssrc/core_main.rssrc/flutter_ffi.rssrc/hbbs_http.rssrc/hbbs_http/downloader.rssrc/hbbs_http/http_client.rssrc/lang/ar.rssrc/lang/be.rssrc/lang/bg.rssrc/lang/ca.rssrc/lang/cn.rssrc/lang/cs.rssrc/lang/da.rssrc/lang/de.rssrc/lang/el.rssrc/lang/eo.rssrc/lang/es.rssrc/lang/et.rssrc/lang/eu.rssrc/lang/fa.rssrc/lang/fi.rssrc/lang/fr.rssrc/lang/ge.rssrc/lang/gu.rssrc/lang/he.rssrc/lang/hi.rssrc/lang/hr.rssrc/lang/hu.rssrc/lang/id.rssrc/lang/it.rssrc/lang/ja.rssrc/lang/ko.rssrc/lang/kz.rssrc/lang/lt.rssrc/lang/lv.rssrc/lang/ml.rssrc/lang/nb.rssrc/lang/nl.rssrc/lang/pl.rssrc/lang/pt_PT.rssrc/lang/ptbr.rssrc/lang/ro.rssrc/lang/ru.rssrc/lang/sc.rssrc/lang/sk.rssrc/lang/sl.rssrc/lang/sq.rssrc/lang/sr.rssrc/lang/sv.rssrc/lang/ta.rssrc/lang/template.rssrc/lang/th.rssrc/lang/tr.rssrc/lang/tw.rssrc/lang/uk.rssrc/lang/vi.rssrc/platform/macos.rssrc/platform/privileges_scripts/update.scptsrc/platform/windows.rssrc/updater.rs
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
@coderabbitai review |
✅ Action performedReview finished.
|
e06f871 to
5990260
Compare
|
@coderabbitai review |
✅ Action performedReview finished.
|
5990260 to
62cc8be
Compare
Signed-off-by: fufesou <linlong1266@gmail.com>
62cc8be to
badb077
Compare
Switch RustDesk updates to signed release metadata.
Summary by CodeRabbit
New Features
Bug Fixes
Tests
Documentation