fix: [Bug] AppFlowy crashes on Windows ARM (issue #8491)#8509
fix: [Bug] AppFlowy crashes on Windows ARM (issue #8491)#8509ipezygj wants to merge 13 commits intoAppFlowy-IO:mainfrom
Conversation
Reviewer's GuideImproves robustness and safety of appflowy.yaml config handling in the Rust FFI layer, but also introduces unrelated AI helper script and various stray Gandalf AI comments/tests that should likely not be part of this PR. File-Level Changes
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
ipezygj seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. You have signed the CLA already but the status is still pending? Let us recheck it. |
There was a problem hiding this comment.
Hey - I've found 2 security issues, 2 other issues, and left some high level feedback:
Security issues:
- Detected subprocess function 'check_output' 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)
- Found 'subprocess' function 'check_output' with 'shell=True'. This is dangerous because this call will spawn the command using a shell process. Doing so propagates current shell settings and variables, which makes it much easier for a malicious actor to execute commands. Use 'shell=False' instead. (link)
General comments:
- Several files (e.g., collab_builder.rs, chat_event.rs, database_event.rs, file_storage.rs) now contain Gandalf/AI-related placeholder comments that don’t change behavior; these should be removed to avoid noise and keep the codebase focused on functional changes.
- The new gandalf_botti.py script appears to be an ad‑hoc automation tool that interacts with
ghand embeds workflow logic (including pushing branches and creating PRs); consider excluding this from the main repo (e.g., keep it in a separate tooling repo or as a local script) to avoid accidental execution and to keep the project tree focused on application code. - In
read_yaml_file, theserde_yaml::from_strmap_errclosure currently returns the rawserde_yaml::Errorwhile the function’s error type isBox<dyn std::error::Error>; this likely won’t type‑check and should instead wrap the error into aBox<dyn Error>inside the closure.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Several files (e.g., collab_builder.rs, chat_event.rs, database_event.rs, file_storage.rs) now contain Gandalf/AI-related placeholder comments that don’t change behavior; these should be removed to avoid noise and keep the codebase focused on functional changes.
- The new gandalf_botti.py script appears to be an ad‑hoc automation tool that interacts with `gh` and embeds workflow logic (including pushing branches and creating PRs); consider excluding this from the main repo (e.g., keep it in a separate tooling repo or as a local script) to avoid accidental execution and to keep the project tree focused on application code.
- In `read_yaml_file`, the `serde_yaml::from_str` `map_err` closure currently returns the raw `serde_yaml::Error` while the function’s error type is `Box<dyn std::error::Error>`; this likely won’t type‑check and should instead wrap the error into a `Box<dyn Error>` inside the closure.
## Individual Comments
### Comment 1
<location> `frontend/rust-lib/dart-ffi/src/appflowy_yaml.rs:28-34` </location>
<code_context>
+ }
+ }
+
+ let mut config = match read_yaml_file(&file_path) {
+ Ok(c) => c,
+ Err(e) => {
+ warn!("Could not read appflowy.yaml (using default): {}", e);
+ AppFlowyYamlConfiguration::default()
+ }
+ };
</code_context>
<issue_to_address>
**suggestion:** Consider avoiding double-logging YAML read/parse errors between `read_yaml_file` and the caller.
`read_yaml_file` already logs parse errors with `error!`, and `save_appflowy_cloud_config` adds another `warn!` when it sees an `Err`, so the same failure gets logged twice. Either make `read_yaml_file` return errors without logging and handle logging only at call sites, or keep logging in `read_yaml_file` and treat errors here as `unwrap_or_default()` without an extra log entry.
```suggestion
let mut config: AppFlowyYamlConfiguration = read_yaml_file(&file_path).unwrap_or_default();
```
</issue_to_address>
### Comment 2
<location> `frontend/rust-lib/dart-ffi/src/appflowy_yaml.rs:56-60` </location>
<code_context>
- let mut file = File::open(file_path)?;
+ let path = file_path.as_ref();
+
+ if !path.exists() {
+ return Ok(AppFlowyYamlConfiguration::default());
+ }
+
+ let mut file = File::open(path)?;
let mut contents = String::new();
file.read_to_string(&mut contents)?;
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Avoid the extra `exists()` check and rely on `File::open` error handling instead.
This adds an extra syscall and a small TOCTOU window before `File::open(path)`. Instead, call `File::open(path)` directly and match on `io::ErrorKind::NotFound` to return the default, which is both cheaper and more robust.
Suggested implementation:
```rust
let path = file_path.as_ref();
let mut file = match File::open(path) {
Ok(file) => file,
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
return Ok(AppFlowyYamlConfiguration::default());
}
Err(e) => return Err(Box::new(e)),
};
let mut contents = String::new();
```
```rust
file.read_to_string(&mut contents)?;
```
</issue_to_address>
### Comment 3
<location> `gandalf_botti.py:9` </location>
<code_context>
return subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, env=env).decode('utf-8')
</code_context>
<issue_to_address>
**security (python.lang.security.audit.dangerous-subprocess-use-audit):** Detected subprocess function 'check_output' 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>
### Comment 4
<location> `gandalf_botti.py:9` </location>
<code_context>
return subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, env=env).decode('utf-8')
</code_context>
<issue_to_address>
**security (python.lang.security.audit.subprocess-shell-true):** Found 'subprocess' function 'check_output' with 'shell=True'. This is dangerous because this call will spawn the command using a shell process. Doing so propagates current shell settings and variables, which makes it much easier for a malicious actor to execute commands. Use 'shell=False' instead.
```suggestion
return subprocess.check_output(cmd, shell=False, stderr=subprocess.STDOUT, env=env).decode('utf-8')
```
*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.
| let mut config = match read_yaml_file(&file_path) { | ||
| Ok(c) => c, | ||
| Err(e) => { | ||
| warn!("Could not read appflowy.yaml (using default): {}", e); | ||
| AppFlowyYamlConfiguration::default() | ||
| } | ||
| }; |
There was a problem hiding this comment.
suggestion: Consider avoiding double-logging YAML read/parse errors between read_yaml_file and the caller.
read_yaml_file already logs parse errors with error!, and save_appflowy_cloud_config adds another warn! when it sees an Err, so the same failure gets logged twice. Either make read_yaml_file return errors without logging and handle logging only at call sites, or keep logging in read_yaml_file and treat errors here as unwrap_or_default() without an extra log entry.
| let mut config = match read_yaml_file(&file_path) { | |
| Ok(c) => c, | |
| Err(e) => { | |
| warn!("Could not read appflowy.yaml (using default): {}", e); | |
| AppFlowyYamlConfiguration::default() | |
| } | |
| }; | |
| let mut config: AppFlowyYamlConfiguration = read_yaml_file(&file_path).unwrap_or_default(); |
| if !path.exists() { | ||
| return Ok(AppFlowyYamlConfiguration::default()); | ||
| } | ||
|
|
||
| let mut file = File::open(path)?; |
There was a problem hiding this comment.
suggestion (bug_risk): Avoid the extra exists() check and rely on File::open error handling instead.
This adds an extra syscall and a small TOCTOU window before File::open(path). Instead, call File::open(path) directly and match on io::ErrorKind::NotFound to return the default, which is both cheaper and more robust.
Suggested implementation:
let path = file_path.as_ref();
let mut file = match File::open(path) {
Ok(file) => file,
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
return Ok(AppFlowyYamlConfiguration::default());
}
Err(e) => return Err(Box::new(e)),
};
let mut contents = String::new(); file.read_to_string(&mut contents)?;| token = subprocess.getoutput("gh auth token").strip() | ||
| env["GITHUB_TOKEN"] = token | ||
| try: | ||
| return subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, env=env).decode('utf-8') |
There was a problem hiding this comment.
security (python.lang.security.audit.dangerous-subprocess-use-audit): Detected subprocess function 'check_output' 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
| token = subprocess.getoutput("gh auth token").strip() | ||
| env["GITHUB_TOKEN"] = token | ||
| try: | ||
| return subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, env=env).decode('utf-8') |
There was a problem hiding this comment.
security (python.lang.security.audit.subprocess-shell-true): Found 'subprocess' function 'check_output' with 'shell=True'. This is dangerous because this call will spawn the command using a shell process. Doing so propagates current shell settings and variables, which makes it much easier for a malicious actor to execute commands. Use 'shell=False' instead.
| return subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, env=env).decode('utf-8') | |
| return subprocess.check_output(cmd, shell=False, stderr=subprocess.STDOUT, env=env).decode('utf-8') |
Source: opengrep
🧙♂️ Gandalf AI (Claude 4.5 Opus) fix for #8491
Summary by Sourcery
Improve robustness of appflowy.yaml configuration handling and add an automation script, along with minor non-functional comment and documentation changes.
Bug Fixes:
Enhancements:
Documentation:
Chores: