Files
ElyOffice/tasks/reviews/C01.2b-r1.md
T

4.4 KiB
Raw Blame History

FAIL

Ran cargo test -p ely-platform (all pass) and cargo clippy -p ely-platform --all-targets (clean). Probes A–C ran against a local server in a scratch crate that depends on ely-platform.

  1. crates/ely-platform/src/update.rs:221-230: The rule "https only, loopback excepted" can be bypassed with userinfo. The code checks the URL by string prefix, and "http://127.0.0.1:" + anything passes. ureq treats 127.0.0.1:1@ as userinfo and connects to the host after @. Scenario (probe B): check(.., "http://127.0.0.1:1@192.168.31.221:PORT/latest.json") returned Ok(Available(..)). The server logged host: 192.168.31.221, so the manifest came over plain http from a non-loopback host. Whoever controls the network then picks the URL and the sha256, and the downloaded file passes verification. plain_http_is_for_this_machine_only does not cover this case. Fix: parse the URL with http::Uri or ureq::http::Uri, reject userinfo, and decide by scheme plus the parsed host. Add the userinfo case to the test.

  2. crates/ely-platform/src/update.rs:77, 232-246: ensure_secure checks only the first URL. Both agents use ureq's defaults (max_redirects 10, https_only false), so redirects to http:// are followed for the manifest and for the download. Scenario (probe A): http://127.0.0.1:P/redirect answered 302 to http://192.168.31.221:P/latest.json. check followed it and returned Available. An https:// manifest URL that redirects to http:// is followed the same way, so the manifest arrives over plain http. Fix: check every hop. Either turn redirects off (max_redirects(0)) and follow Location manually through ensure_secure, or use https_only(true) for non-loopback URLs. Add a test where a redirect leaves loopback.

  3. crates/ely-platform/src/update.rs:175-180, 239-246: The comment "the user can cancel" is not true. The download agent has no read timeout, and the cancel flag is checked only between read calls. A stalled connection blocks read forever: cancel does nothing, and no error is ever returned. Scenario (probe C): the server sent the headers and 1000 of 1000000 bytes, then went silent. I set cancel to true 1 s in. download was still blocked 19 s later. In the field, a dropped Wi-Fi link or a hung CDN leaves the download hung for good. Fix: put an idle-read timeout on the socket (for example a custom connector or transport with set_read_timeout) so that read returns, cancel is honoured, and a stall becomes an error. Add a test with a stalled server.

  4. crates/ely-platform/src/update.rs:62, 66-73: APPIMAGE is an inherited environment variable, and it overrides the package-manager prefixes. A distro-installed binary launched from inside any AppImage is treated as SelfManaged. Scenario: the user starts a terminal emulator or editor that ships as an AppImage, then runs /usr/bin/ely-doc (installed by pacman) from its terminal. APPIMAGE is set, so install_policy() returns SelfManaged and the app would update itself over files the package manager owns. This breaks PRD §4.2 ("Linux 包管理器安装的版本不绕过包管理器自行覆盖文件"). Fix: count it as an AppImage only when current_exe lies under $APPDIR (the mount of this AppImage), not just because APPIMAGE exists. Cover the inherited-variable case in the unit test.

  5. crates/ely-platform/src/update.rs:142-147: The download's own error is lost when removing the .part file fails, because the ? on remove_file returns the removal error instead. Scenario: the hash does not match, and on Windows an antivirus scanner still holds ElyDoc.exe.part. The caller sees "cannot remove …part", and "the file has sha256 X, the release says Y" never reaches the user. Fix: keep the original error and attach the removal failure to it, or log the removal failure and still return the original error.

  6. crates/ely-platform/src/update.rs:76-102, 138-141: Rule 4 (key paths are logged) is not met. check makes a network request and logs neither the request nor the outcome (current, available, or which failure). A cancelled download is not logged either. Only a successful download logs anything. Scenario: QA-25 asks for an audit of outgoing update requests, and a user reports "check for updates does nothing". The log has no line showing a check was made or what it returned. Fix: log the manifest host and the result in check, and log a cancelled download (version only, no secrets).