TEST#6
Conversation
…re missing, replaced mentions of the old GitHub by the new repo, fixed the issue Hogjects#200. No AI used.
Please enter the commit message for your changes. Lines starting with '' will be ignored, and an empty message aborts the commit. On branch dev Your branch is up to date with 'origin/dev'. Changes to be committed: modified: src/lufus/gui/dialogs.py modified: src/lufus/gui/gui.py modified: src/lufus/gui/languages/Deutsch.csv modified: src/lufus/gui/languages/English.csv modified: "src/lufus/gui/languages/Espa\303\261ol.csv" modified: "src/lufus/gui/languages/Fran\303\247ais.csv" modified: "src/lufus/gui/languages/Portugue\314\202s Brasileiro.csv" modified: src/lufus/gui/languages/Svenska.csv modified: "src/lufus/gui/languages/\320\240\321\203\321\201\321\201\320\272\320\270\320\271.csv" modified: "src/lufus/gui/languages/\321\203\320\272\321\200\320\260\321\227\320\275\321\201\321\214\320\272\320\260.csv" modified: "src/lufus/gui/languages/\330\271\330\261\330\250\331\212.csv" modified: "src/lufus/gui/languages/\340\246\254\340\246\276\340\246\202\340\246\262\340\246\276.csv"
Please enter the commit message for your changes. Lines starting with '' will be ignored, and an empty message aborts the commit. On branch dev Your branch is ahead of 'origin/dev' by 1 commit. (use "git push" to publish your local commits) Changes to be committed: modified: src/lufus/gui/dialogs.py modified: src/lufus/gui/gui.py modified: "src/lufus/gui/languages/Espa\303\261ol.csv" modified: "src/lufus/gui/languages/\320\240\321\203\321\201\321\201\320\272\320\270\320\271.csv" modified: "src/lufus/gui/languages/\321\203\320\272\321\200\320\260\321\227\320\275\321\201\321\214\320\272\320\260.csv" modified: "src/lufus/gui/languages/\330\271\330\261\330\250\331\212.csv" modified: "src/lufus/gui/languages/\340\246\254\340\246\276\340\246\202\340\246\262\340\246\276.csv"
…d some scaling. Please enter the commit message for your changes. Lines starting with '' will be ignored, and an empty message aborts the commit. On branch dev Your branch is ahead of 'origin/dev' by 2 commits. (use "git push" to publish your local commits) Changes to be committed: new file: src/lufus/browse_freely.py modified: src/lufus/gui/dialogs.py modified: src/lufus/gui/gui.py
Please enter the commit message for your changes. Lines starting with '' will be ignored, and an empty message aborts the commit. On branch dev Your branch is ahead of 'origin/dev' by 4 commits. (use "git push" to publish your local commits) Changes to be committed: new file: tests/test_browse_freely.py
Reviewer's GuideRefactors low-level device, filesystem, and ISO handling to use new pure‑Python helpers instead of external utilities, tightens Windows flashing/tweaks behavior and bad‑block checking, improves GUI UX (language/theme persistence, safer flashing flow, better URL opening), and updates build metadata and tests for the new architecture. Sequence diagram for updated flashing, bad-block check, and Windows tweakssequenceDiagram
actor User
participant GUI as LufusWindow
participant Verify as VerifyWorker
participant Flash as FlashWorker
participant Format as formatting.check_device_bad_blocks
participant WinFlash as windows.flash.flash_windows
participant Tweaks as windows.tweaks.apply_windows_tweaks
User ->> GUI: click btn_start
GUI ->> GUI: start_process()
alt verify_hash enabled
GUI ->> Verify: start()
Verify -->> GUI: int_progress(0..100)
Verify -->> GUI: verify_done(success)
GUI ->> GUI: on_verify_finished(success)
end
GUI ->> GUI: perform_flash()
GUI ->> User: QMessageBox (Rufus-style warning)
alt user cancels
GUI ->> GUI: abort flash
GUI -->> User: flash cancelled
else user confirms
GUI ->> Flash: start()
end
Flash ->> Flash: run()
alt states.check_bad
Flash ->> Format: check_device_bad_blocks(passes=states.bad_blocks_passes)
Format -->> Flash: bool
alt bad block check failed
Flash -->> GUI: flash_done(False)
GUI -->> User: show failure
note over Flash,GUI: return
end
end
alt Windows ISO and flash mode ISO
Flash ->> WinFlash: flash_windows(device, iso, scheme,...)
WinFlash ->> Tweaks: apply_windows_tweaks(mount_data)
Tweaks -->> WinFlash: bool
WinFlash -->> Flash: bool
else DD image mode
Flash ->> WinFlash: (not called)
end
Flash -->> GUI: flash_done(success)
GUI ->> GUI: on_flash_finished(success)
GUI -->> User: show result
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 2 issues, and left some high level feedback:
- In
launch_gui_with_usb_data,_load_initial_language()is called both before and afterelevate_privileges(), which means the post-elevation call may read the root user’s config and overwrite the intended user language; consider only initializing language in the non-root context or guarding the second call appropriately. - In
open_url_non_root, when onlySUDO_USERis set you never derive a UID, soXDG_RUNTIME_DIRis left empty; consider resolving the UID forsudo_user(e.g. viapwd.getpwnam) to populate a more accurate environment for GUI apps.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `launch_gui_with_usb_data`, `_load_initial_language()` is called both before and after `elevate_privileges()`, which means the post-elevation call may read the root user’s config and overwrite the intended user language; consider only initializing language in the non-root context or guarding the second call appropriately.
- In `open_url_non_root`, when only `SUDO_USER` is set you never derive a UID, so `XDG_RUNTIME_DIR` is left empty; consider resolving the UID for `sudo_user` (e.g. via `pwd.getpwnam`) to populate a more accurate environment for GUI apps.
## Individual Comments
### Comment 1
<location path="src/lufus/browse_freely.py" line_range="39" />
<code_context>
+
+ # Method 1: Use runuser which is specifically designed for this
+ # We need to preserve the environment for the GUI session
+ env = {
+ "DISPLAY": os.environ.get("DISPLAY", ":0"),
+ "XAUTHORITY": os.environ.get("XAUTHORITY", ""),
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Environment for the spawned browser process does not set HOME, which may cause profile or permission issues.
Since many GUI apps depend on `HOME` for profiles and config, relying only on `DISPLAY`, `XAUTHORITY`, `XDG_RUNTIME_DIR`, `WAYLAND_DISPLAY`, and `PATH` risks using root’s home (or none) when running as another user, especially in the `sudo_user` case without `target_uid`. Please also set `HOME` to the target user’s home directory (e.g. `pwd.getpwnam(target_user).pw_dir`) and add it to `env` when available.
Suggested implementation:
```python
import os
import pwd
```
```python
if target_user:
try:
log.info(f"Attempting to open URL as user {target_user} (UID {target_uid}): {url}")
# Determine the target user's home directory so GUI apps use the correct profile/config
home_dir = None
try:
home_dir = pwd.getpwnam(target_user).pw_dir
except KeyError:
log.warning("Could not determine home directory for user %s", target_user)
# Method 1: Use runuser which is specifically designed for this
# We need to preserve the environment for the GUI session
env = {
"DISPLAY": os.environ.get("DISPLAY", ":0"),
"XAUTHORITY": os.environ.get("XAUTHORITY", ""),
"XDG_RUNTIME_DIR": os.environ.get(
"XDG_RUNTIME_DIR", f"/run/user/{target_uid}" if target_uid else ""
),
"WAYLAND_DISPLAY": os.environ.get("WAYLAND_DISPLAY", ""),
"PATH": "/usr/local/bin:/usr/bin:/bin",
# Ensure HOME is set so GUI apps use the target user's profile and config
"HOME": home_dir or os.environ.get("HOME", ""),
}
# Filter out empty values
env = {k: v for k, v in env.items() if v}
```
If `pwd` is already imported elsewhere in this file, adjust the import edit accordingly to avoid duplicate imports (e.g. by adding it to an existing import line instead of introducing a new one).
</issue_to_address>
### Comment 2
<location path="tests/test_browse_freely.py" line_range="11-20" />
<code_context>
+ self.assertEqual(env.get("DISPLAY"), ":0")
+ self.assertEqual(env.get("XDG_RUNTIME_DIR"), "/run/user/1000")
+
+ @patch("os.geteuid")
+ @patch("os.environ.get")
+ @patch("subprocess.Popen")
+ def test_open_url_as_root_via_sudo(self, mock_popen, mock_env_get, mock_geteuid):
+ # Simulate root (UID 0)
+ mock_geteuid.return_value = 0
</code_context>
<issue_to_address>
**suggestion (testing):** Consider using `patch.dict(os.environ, ...)` instead of patching `os.environ.get` to make the tests more realistic and resilient.
Patching `os.environ.get` with a `side_effect` intercepts every env lookup (e.g. `DISPLAY`, `XAUTHORITY`, `XDG_RUNTIME_DIR`), which couples the tests to the exact way `open_url_non_root` reads the environment. Instead, patching `os.environ` via `patch.dict(os.environ, {"PKEXEC_UID": "1000", ...}, clear=False)` (and similarly for the sudo case) more accurately reflects real usage and keeps the tests resilient to internal changes in environment access.
Suggested implementation:
```python
@patch("os.geteuid")
@patch("subprocess.Popen")
@patch("pwd.getpwuid")
def test_open_url_as_root_via_pkexec(self, mock_getpwuid, mock_popen, mock_geteuid):
```
```python
# Mock environment variables
env_overrides = {
"PKEXEC_UID": "1000",
"DISPLAY": ":0",
"XDG_RUNTIME_DIR": "/run/user/1000",
}
with patch.dict(os.environ, env_overrides, clear=False):
open_url_non_root(self.url)
# Mock pwd info
```
1. Apply a similar refactor to the `test_open_url_as_root_via_sudo` test: remove any `@patch("os.environ.get")` decorator and associated `mock_env_get` parameter, and replace any `side_effect`-based environment mocking with a `with patch.dict(os.environ, {...}, clear=False):` block that sets the sudo-related variables your production code expects (e.g. `SUDO_USER`, `DISPLAY`, `XDG_RUNTIME_DIR`, etc.), wrapping the `open_url_non_root(self.url)` call in that context.
2. If there are other tests in this file that also patch `os.environ.get`, consider converting them to `patch.dict` in the same way to keep the test suite consistent and resilient to internal environment access changes.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| @patch("os.geteuid") | ||
| @patch("webbrowser.open") | ||
| def test_open_url_non_root_as_regular_user(self, mock_webbrowser, mock_geteuid): | ||
| # Simulate regular user (UID 1000) | ||
| mock_geteuid.return_value = 1000 | ||
|
|
||
| open_url_non_root(self.url) | ||
|
|
||
| # Should fallback to standard webbrowser.open | ||
| mock_webbrowser.assert_called_once_with(self.url) |
There was a problem hiding this comment.
suggestion (testing): Consider using patch.dict(os.environ, ...) instead of patching os.environ.get to make the tests more realistic and resilient.
Patching os.environ.get with a side_effect intercepts every env lookup (e.g. DISPLAY, XAUTHORITY, XDG_RUNTIME_DIR), which couples the tests to the exact way open_url_non_root reads the environment. Instead, patching os.environ via patch.dict(os.environ, {"PKEXEC_UID": "1000", ...}, clear=False) (and similarly for the sudo case) more accurately reflects real usage and keeps the tests resilient to internal changes in environment access.
Suggested implementation:
@patch("os.geteuid")
@patch("subprocess.Popen")
@patch("pwd.getpwuid")
def test_open_url_as_root_via_pkexec(self, mock_getpwuid, mock_popen, mock_geteuid): # Mock environment variables
env_overrides = {
"PKEXEC_UID": "1000",
"DISPLAY": ":0",
"XDG_RUNTIME_DIR": "/run/user/1000",
}
with patch.dict(os.environ, env_overrides, clear=False):
open_url_non_root(self.url)
# Mock pwd info- Apply a similar refactor to the
test_open_url_as_root_via_sudotest: remove any@patch("os.environ.get")decorator and associatedmock_env_getparameter, and replace anyside_effect-based environment mocking with awith patch.dict(os.environ, {...}, clear=False):block that sets the sudo-related variables your production code expects (e.g.SUDO_USER,DISPLAY,XDG_RUNTIME_DIR, etc.), wrapping theopen_url_non_root(self.url)call in that context. - If there are other tests in this file that also patch
os.environ.get, consider converting them topatch.dictin the same way to keep the test suite consistent and resilient to internal environment access changes.
|
@sourcery-ai review |
There was a problem hiding this comment.
Hey - I've found 2 issues
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="src/lufus/gui/i18n.py" line_range="29-38" />
<code_context>
+ Falls back to English if detection fails or no match is found.
+ """
+ try:
+ loc = locale.getdefaultlocale()
+ except Exception:
+ loc = (None, None)
</code_context>
<issue_to_address>
**suggestion:** Using `locale.getdefaultlocale()` may be problematic going forward due to deprecation; consider an alternative approach.
`locale.getdefaultlocale()` is deprecated in recent Python versions and may be removed. Since only the language is needed, consider alternatives such as `locale.getlocale()[0]`, `os.environ.get("LANG")`, or `locale.setlocale(locale.LC_CTYPE, "")` followed by `locale.getlocale()` to avoid relying on a deprecated API.
```suggestion
def detect_system_language() -> str:
"""Detect the system locale and return the matching language name.
Falls back to English if detection fails or no match is found.
"""
try:
# Ensure locale is initialized from the environment, then read current locale.
locale.setlocale(locale.LC_CTYPE, "")
loc = locale.getlocale()
except Exception:
loc = (None, None)
lang_code = (loc[0] or "") or os.environ.get("LANG", "")
```
</issue_to_address>
### Comment 2
<location path="tests/test_flash_usb_and_find_usb_fixes.py" line_range="148-149" />
<code_context>
pass
class FakePipe:
- def readline(self):
+ def read(self, n=-1):
return b""
</code_context>
<issue_to_address>
**suggestion (testing):** Strengthen the fake stderr pipe to assert that `read` is called with the expected chunk size (4096).
`FakePipe.read` currently ignores `n` and always returns `b""`, so the test doesn’t verify that `process.stderr.read(4096)` is actually called with the intended chunk size. Consider recording the passed-in `n` (e.g., `self.last_n = n`) and asserting it is `4096` (or at least `> 0`) after the call to catch regressions like switching back to `readline()` or changing the chunk size.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| class FakePipe: | ||
| def readline(self): | ||
| def read(self, n=-1): |
There was a problem hiding this comment.
suggestion (testing): Strengthen the fake stderr pipe to assert that read is called with the expected chunk size (4096).
FakePipe.read currently ignores n and always returns b"", so the test doesn’t verify that process.stderr.read(4096) is actually called with the intended chunk size. Consider recording the passed-in n (e.g., self.last_n = n) and asserting it is 4096 (or at least > 0) after the call to catch regressions like switching back to readline() or changing the chunk size.
|
@sourcery-ai review |
There was a problem hiding this comment.
Hey - I've found 1 issue
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="src/lufus/gui/i18n.py" line_range="34-41" />
<code_context>
+ Falls back to English if detection fails or no match is found.
+ """
+ try:
+ # Ensure locale is initialized from the environment, then read current locale.
+ locale.setlocale(locale.LC_CTYPE, "")
+ loc = locale.getlocale()
+ except Exception:
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Calling `locale.setlocale` here mutates global process state and may have unintended side effects.
`locale.setlocale(locale.LC_CTYPE, "")` here mutates the global locale and can unexpectedly impact formatting/parsing and libraries that depend on locale (e.g. Qt). If you only need to detect the system locale, prefer `locale.getdefaultlocale()` or environment variables (e.g. `$LANG`) without changing the active locale, or temporarily change it and immediately restore the original value.
```suggestion
try:
# Read the system locale without mutating global locale state.
loc = locale.getdefaultlocale()
except Exception:
loc = (None, None)
# Fallback to the process locale if the default locale could not be determined.
if not loc or not loc[0]:
try:
loc = locale.getlocale()
except Exception:
loc = (None, None)
lang_code = (loc[0] or "") or os.environ.get("LANG", "")
```
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
|
broke smth i think |
|
@sourcery-ai review |
There was a problem hiding this comment.
Hey - I've found 1 issue, and left some high level feedback:
- open_url_non_root() unconditionally calls os.geteuid(), which will raise on platforms without that API (e.g. Windows); consider guarding this with hasattr/os.name checks or a try/except and treating such platforms as non-root so the function safely falls back to webbrowser.open.
- _load_initial_language() swallows all exceptions and may leave state.language unset or stale; it would be safer to explicitly default to 'English' (or another known language) when detection/persistence fails so the GUI always has a predictable language value.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- open_url_non_root() unconditionally calls os.geteuid(), which will raise on platforms without that API (e.g. Windows); consider guarding this with hasattr/os.name checks or a try/except and treating such platforms as non-root so the function safely falls back to webbrowser.open.
- _load_initial_language() swallows all exceptions and may leave state.language unset or stale; it would be safer to explicitly default to 'English' (or another known language) when detection/persistence fails so the GUI always has a predictable language value.
## Individual Comments
### Comment 1
<location path="src/lufus/browse_freely.py" line_range="43-55" />
<code_context>
+
+ # Method 1: Use runuser which is specifically designed for this
+ # We need to preserve the environment for the GUI session
+ env = {
+ "DISPLAY": os.environ.get("DISPLAY", ":0"),
+ "XAUTHORITY": os.environ.get("XAUTHORITY", ""),
+ "XDG_RUNTIME_DIR": os.environ.get(
+ "XDG_RUNTIME_DIR", f"/run/user/{target_uid}" if target_uid else ""
+ ),
+ "WAYLAND_DISPLAY": os.environ.get("WAYLAND_DISPLAY", ""),
+ "PATH": "/usr/local/bin:/usr/bin:/bin",
+ # Ensure HOME is set so GUI apps use the target user's profile and config
+ "HOME": home_dir or os.environ.get("HOME", ""),
+ }
+
</code_context>
<issue_to_address>
**suggestion:** Environment for `runuser` may be missing session-related variables needed by some desktop environments.
For `xdg-open` via `runuser`, some DEs (especially under Wayland) also depend on `DBUS_SESSION_BUS_ADDRESS` and similar session vars. Consider propagating it when present, for example:
```python
env = {
"DISPLAY": os.environ.get("DISPLAY", ":0"),
"XAUTHORITY": os.environ.get("XAUTHORITY", ""),
"XDG_RUNTIME_DIR": os.environ.get(
"XDG_RUNTIME_DIR", f"/run/user/{target_uid}" if target_uid else ""
),
"WAYLAND_DISPLAY": os.environ.get("WAYLAND_DISPLAY", ""),
"DBUS_SESSION_BUS_ADDRESS": os.environ.get("DBUS_SESSION_BUS_ADDRESS", ""),
"PATH": "/usr/local/bin:/usr/bin:/bin",
"HOME": home_dir or os.environ.get("HOME", ""),
}
```
This reduces cases where `xdg-open` fails under certain desktop environments.
```suggestion
# Method 1: Use runuser which is specifically designed for this
# We need to preserve the environment for the GUI session
env = {
"DISPLAY": os.environ.get("DISPLAY", ":0"),
"XAUTHORITY": os.environ.get("XAUTHORITY", ""),
"XDG_RUNTIME_DIR": os.environ.get(
"XDG_RUNTIME_DIR", f"/run/user/{target_uid}" if target_uid else ""
),
"WAYLAND_DISPLAY": os.environ.get("WAYLAND_DISPLAY", ""),
# Propagate DBUS session bus so xdg-open works under more DEs/Wayland sessions
"DBUS_SESSION_BUS_ADDRESS": os.environ.get("DBUS_SESSION_BUS_ADDRESS", ""),
"PATH": "/usr/local/bin:/usr/bin:/bin",
# Ensure HOME is set so GUI apps use the target user's profile and config
"HOME": home_dir or os.environ.get("HOME", ""),
}
```
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
|
Dgaf about windows lmao |
|
and Hogjects#184, too |
Please enter the commit message for your changes. Lines starting with '' will be ignored, and an empty message aborts the commit. On branch dev Your branch is up to date with 'origin/dev'. Changes to be committed: new file: src/lufus/block_ops.py modified: src/lufus/drives/find_usb.py modified: src/lufus/drives/formatting.py modified: src/lufus/drives/get_usb_info.py modified: src/lufus/gui/gui.py new file: src/lufus/iso9660.py modified: src/lufus/writing/flash_usb.py modified: src/lufus/writing/install_ventoy.py modified: src/lufus/writing/windows/detect.py modified: src/lufus/writing/windows/flash.py modified: src/lufus/writing/windows/tweaks.py modified: tests/test_find_usb.py modified: tests/test_flash_usb_and_find_usb_fixes.py modified: tests/test_formatting.py modified: tests/test_get_usb_info.py modified: tests/test_get_usb_info_and_detect_windows_fixes.py modified: tests/test_linux_iso_detection.py
|
Gonna test the new DVD stuff later w/ my thinkPad |
Please enter the commit message for your changes. Lines starting with '' will be ignored, and an empty message aborts the commit. On branch dev Your branch is ahead of 'origin/dev' by 1 commit. (use "git push" to publish your local commits) Changes to be committed: modified: src/lufus/drives/formatting.py modified: src/lufus/gui/gui.py modified: src/lufus/gui/workers.py modified: src/lufus/state.py modified: tests/test_states_and_autodetect_fixes.py
|
I think I fixed Hogjects#206 |
| (mkfs.*, wimlib-imagex, package managers). | ||
| """ | ||
| try: | ||
| return subprocess.run(cmd, check=check) |
There was a problem hiding this comment.
security (python.lang.security.audit.dangerous-subprocess-use-audit): Detected subprocess function 'run' without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'.
Source: opengrep
|
@sourcery-ai review |
There was a problem hiding this comment.
Hey - I've found 1 security issue, 1 other issue, and left some high level feedback:
Security issues:
- Detected subprocess function 'run' without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'. (link)
General comments:
- The block device wiping logic is now duplicated between
block_ops.wipe_superblockand the manual per-partition zeroing indrives/formatting._format_device; consider centralizing this into a single helper inblock_opsto avoid divergent behavior and make future changes easier. - In
block_ops.umount, allumount2failures are logged as warnings; you may want to special-case benign errors such asEINVAL/ENOENT("not mounted") to avoid noisy logs when unmounting already-unmounted paths.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The block device wiping logic is now duplicated between `block_ops.wipe_superblock` and the manual per-partition zeroing in `drives/formatting._format_device`; consider centralizing this into a single helper in `block_ops` to avoid divergent behavior and make future changes easier.
- In `block_ops.umount`, all `umount2` failures are logged as warnings; you may want to special-case benign errors such as `EINVAL`/`ENOENT` ("not mounted") to avoid noisy logs when unmounting already-unmounted paths.
## Individual Comments
### Comment 1
<location path="src/lufus/drives/formatting.py" line_range="70-75" />
<code_context>
+ if umount_lazy(target):
</code_context>
<issue_to_address>
**issue (bug_risk):** New unmount logic can silently treat real umount failures as benign
Previously, `unmount()` treated exit code 32 as “not mounted” but aborted on other umount failures (e.g. EBUSY, EPERM). Now any `umount_lazy(target)` failure is logged as “already unmounted or not a mount” and processing continues, even when the real error is serious.
This can hide conditions like `EBUSY` or `EPERM`, so later steps (e.g. formatting/partitioning) may run while the device is still mounted. Please have `umount_lazy` expose the underlying error (e.g. via errno or a richer return type) so `unmount()` can still distinguish “not mounted” from real failures and abort or retry as before.
</issue_to_address>
### Comment 2
<location path="src/lufus/writing/windows/flash.py" line_range="37" />
<code_context>
return subprocess.run(cmd, check=check, shell=False)
</code_context>
<issue_to_address>
**security (python.lang.security.audit.dangerous-subprocess-use-audit):** Detected subprocess function 'run' without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'.
*Source: opengrep*
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| if umount_lazy(target): | ||
| time.sleep(0.5) | ||
| log.info("Unmounted %s successfully.", target) | ||
| except subprocess.CalledProcessError as e: | ||
| # exit 32 = "not mounted" on Linux — acceptable when clearing a drive | ||
| if e.returncode == 32: | ||
| log.info("Unmounted %s (was already unmounted).", target) | ||
| continue | ||
| log.error("umount -l %s exited with code %d", target, e.returncode) | ||
| unmount_fail() | ||
| return False | ||
| except Exception as e: | ||
| log.error("(UMNTFUNC) Unexpected error type: %s — %s", type(e).__name__, e) | ||
| log_unexpected_error() | ||
| return False | ||
| subprocess.run(["udevadm", "settle"]) | ||
| else: | ||
| # Target may already be unmounted — not a fatal error | ||
| log.info("Unmounted %s (was already unmounted or not a mount).", target) |
There was a problem hiding this comment.
issue (bug_risk): New unmount logic can silently treat real umount failures as benign
Previously, unmount() treated exit code 32 as “not mounted” but aborted on other umount failures (e.g. EBUSY, EPERM). Now any umount_lazy(target) failure is logged as “already unmounted or not a mount” and processing continues, even when the real error is serious.
This can hide conditions like EBUSY or EPERM, so later steps (e.g. formatting/partitioning) may run while the device is still mounted. Please have umount_lazy expose the underlying error (e.g. via errno or a richer return type) so unmount() can still distinguish “not mounted” from real failures and abort or retry as before.
| (mkfs.*, wimlib-imagex, package managers). | ||
| """ | ||
| try: | ||
| return subprocess.run(cmd, check=check, shell=False) |
There was a problem hiding this comment.
security (python.lang.security.audit.dangerous-subprocess-use-audit): Detected subprocess function 'run' without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'.
Source: opengrep
Please enter the commit message for your changes. Lines starting with '' will be ignored, and an empty message aborts the commit. On branch dev Your branch is up to date with 'origin/dev'. Changes to be committed: modified: pyproject.toml modified: src/lufus/block_ops.py modified: src/lufus/drives/formatting.py modified: src/lufus/gui/gui.py modified: src/lufus/iso9660.py modified: src/lufus/writing/windows/flash.py modified: src/lufus/writing/windows/tweaks.py
|
HOLY- |
|
and theres a bug when i cancel it crashes |
|
@sourcery-ai review |
|
Sorry @Radiump123, your pull request is larger than the review limit of 150000 diff characters |
1 similar comment
|
Sorry @Radiump123, your pull request is larger than the review limit of 150000 diff characters |
sigh |
GPT-5.5's review... Gotta look at that... |
|
Will review my changes later. |
|
" 1. [Security] MITM Risk: Unverified Binary Download
Gemini 3.5 Flash this time, gonna look at it. |
Please enter the commit message for your changes. Lines starting with '' will be ignored, and an empty message aborts the commit. On branch dev Your branch is up to date with 'origin/dev'. Changes to be committed: modified: src/lufus/gui/gui.py modified: src/lufus/gui/workers.py modified: src/lufus/iso9660.py modified: src/lufus/writing/windows/flash.py modified: src/lufus/writing/windows/tweaks.py
|
Ok, I again fucking broke WinTweaks, I'm calling Jesus... |
Please enter the commit message for your changes. Lines starting with '' will be ignored, and an empty message aborts the commit. On branch dev Your branch is ahead of 'origin/dev' by 1 commit. (use "git push" to publish your local commits) Changes to be committed: modified: src/lufus/block_ops.py modified: src/lufus/drives/formatting.py modified: src/lufus/utils.py modified: src/lufus/writing/flash_worker.py modified: src/lufus/writing/windows/tweaks.py modified: tests/test_formatting.py
…est with old ISOs from like Win7 \
to see if detection works properly with wintweaks. Nevermind it broke, let's try and fix this shi.
…rng, gotta fix it. Gonna try w/old windows and random OS/2 Warp too. Might later try to rewrite more parts of the app btw, unrelated to this commit. Like removing subprocesses, using other langs for replacing some if needed...
|
Tested wintweaks, and they don't actually apply btw, gotta test that. |
…. Added a thing to forbid from running two lufus at once. Will add translations.
…ded detection of non-bootable fiels. Might see if its worth it. Please enter the commit message for your changes. Lines starting with '' will be ignored, and an empty message aborts the commit. On branch dev Your branch is ahead of 'origin/dev' by 6 commits. (use "git push" to publish your local commits) Changes to be committed: modified: src/lufus/drives/formatting.py modified: src/lufus/gui/gui.py modified: src/lufus/gui/workers.py modified: src/lufus/iso9660.py modified: src/lufus/lufus_logging.py modified: src/lufus/state.py modified: src/lufus/writing/windows/detect.py modified: src/lufus/writing/windows/tweaks.py new file: tests/test_windows_detection_and_tweaks.py
Please enter the commit message for your changes. Lines starting with '' will be ignored, and an empty message aborts the commit. On branch dev Your branch is ahead of 'origin/dev' by 7 commits. (use "git push" to publish your local commits) Changes to be committed: modified: src/lufus/gui/gui.py modified: src/lufus/iso9660.py modified: src/lufus/writing/windows/detect.py modified: tests/test_windows_detection_and_tweaks.py
…le pop up, wintweaks stilll no works so i gonna fix it. Please enter the commit message for your changes. Lines starting with '' will be ignored, and an empty message aborts the commit. On branch dev Your branch is ahead of 'origin/dev' by 8 commits. (use "git push" to publish your local commits) Changes to be committed: modified: src/lufus/gui/languages/Deutsch.csv modified: src/lufus/gui/languages/English.csv modified: "src/lufus/gui/languages/Espa\303\261ol.csv" modified: "src/lufus/gui/languages/Fran\303\247ais.csv" modified: "src/lufus/gui/languages/Portugue\314\202s Brasileiro.csv" modified: src/lufus/gui/languages/Svenska.csv modified: "src/lufus/gui/languages/\320\240\321\203\321\201\321\201\320\272\320\270\320\271.csv" modified: "src/lufus/gui/languages/\321\203\320\272\321\200\320\260\321\227\320\275\321\201\321\214\320\272\320\260.csv" modified: "src/lufus/gui/languages/\330\271\330\261\330\250\331\212.csv" modified: "src/lufus/gui/languages/\340\246\254\340\246\276\340\246\202\340\246\262\340\246\276.csv" modified: src/lufus/writing/windows/flash.py modified: src/lufus/writing/windows/tweaks.py modified: tests/test_flash_windows_and_install_ventoy_fixes.py Untracked files: src/lufus/writing/windows/uefi-ntfs.img tests/test_i18n_translations.py
Please enter the commit message for your changes. Lines starting with '' will be ignored, and an empty message aborts the commit. On branch dev Your branch is ahead of 'origin/dev' by 9 commits. (use "git push" to publish your local commits) Changes to be committed: new file: src/lufus/writing/windows/uefi-ntfs.img new file: tests/test_i18n_translations.py
Please enter the commit message for your changes. Lines starting with '' will be ignored, and an empty message aborts the commit. On branch dev Your branch is ahead of 'origin/dev' by 10 commits. (use "git push" to publish your local commits) Changes to be committed: modified: src/lufus/gui/dialogs.py modified: src/lufus/gui/gui.py modified: src/lufus/state.py modified: src/lufus/writing/flash_worker.py modified: src/lufus/writing/windows/tweaks.py modified: tests/test_windows_detection_and_tweaks.py
Summary by Sourcery
Replace most external CLI dependencies with internal Python implementations for block device, ISO, and system operations, and integrate Windows tweak application, bad-block checking, and locale/theme/language handling more tightly into the GUI and flashing workflows.
New Features:
Bug Fixes:
Enhancements:
Build:
Tests: