-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Fix: ensure stable YAML serialization by using BTreeMap #5553
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -6,7 +6,7 @@ use once_cell::sync::OnceCell; | |||||
| use serde::{Deserialize, Serialize}; | ||||||
| use serde_json::Value; | ||||||
| use serde_yaml::Mapping; | ||||||
| use std::collections::HashMap; | ||||||
| use std::collections::{HashMap, BTreeMap}; | ||||||
| use std::env; | ||||||
| use std::fs::OpenOptions; | ||||||
| use std::io::Write; | ||||||
|
|
@@ -369,8 +369,18 @@ impl Config { | |||||
| // Create backup before writing new config | ||||||
| self.create_backup_if_needed()?; | ||||||
|
|
||||||
| // Convert to YAML for storage | ||||||
| let yaml_value = serde_yaml::to_string(&values)?; | ||||||
| // Convert to YAML for storage (sorted by key for stable serialization) | ||||||
| let ordered: BTreeMap<String, serde_yaml::Value> = values | ||||||
| .into_iter() | ||||||
| .map(|(k, v)| { | ||||||
| let key = match k { | ||||||
| serde_yaml::Value::String(s) => s, | ||||||
| other => serde_yaml::to_string(&other).unwrap_or_else(|_| format!("{:?}", other)), | ||||||
| }; | ||||||
| (key, v) | ||||||
| }) | ||||||
| .collect(); | ||||||
| let yaml_value = serde_yaml::to_string(&ordered)?; | ||||||
|
|
||||||
| // Ensure the directory exists | ||||||
| if let Some(parent) = self.config_path.parent() { | ||||||
|
|
@@ -701,7 +711,8 @@ impl Config { | |||||
| entry.set_password(&json_value)?; | ||||||
| } | ||||||
| SecretStorage::File { path } => { | ||||||
| let yaml_value = serde_yaml::to_string(&values)?; | ||||||
| let ordered: BTreeMap<String, serde_json::Value> = values.into_iter().collect(); | ||||||
|
||||||
| let ordered: BTreeMap<String, serde_json::Value> = values.into_iter().collect(); | |
| let ordered: BTreeMap<_, _> = values.into_iter().collect(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
serde_yaml::to_stringcall can fail and produce unpredictable fallback keys usingformat!(\"{:?}\", other). This fallback produces Debug output rather than a proper string representation, which could lead to confusing keys in the config file. Consider handling non-string keys more explicitly, or document why non-string keys are expected in aMappingthat should only have string keys.