From 69ed27ba443a4bb8109cde9b56b99076190ae9db Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 25 Apr 2026 13:32:08 +0000 Subject: [PATCH] refactor(sync): reuse storage constants instead of redefining WORKSPACE_METADATA_FILE, LIST_METADATA_FILE and the 64KB frontmatter cap each existed in two places (storage.rs and sync.rs) with identical values. parse_frontmatter_for_conflict even repeated the cap as a magic number with the byte count baked into the error string. Promote the storage definitions to pub(crate) and import them so any future tweak (e.g. raising the frontmatter cap) only needs one edit. --- crates/onyx-core/src/storage.rs | 6 +++--- crates/onyx-core/src/sync.rs | 17 ++++++++--------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/crates/onyx-core/src/storage.rs b/crates/onyx-core/src/storage.rs index 7f8bc8b..58181d2 100644 --- a/crates/onyx-core/src/storage.rs +++ b/crates/onyx-core/src/storage.rs @@ -14,11 +14,11 @@ const MAX_DESCRIPTION_LENGTH: usize = 1_000_000; // 1 MB /// Maximum allowed length for list names. const MAX_LIST_NAME_LENGTH: usize = 255; /// Maximum allowed size for YAML frontmatter (64 KB) to prevent DoS via crafted files. -const MAX_FRONTMATTER_LENGTH: usize = 64 * 1024; +pub(crate) const MAX_FRONTMATTER_LENGTH: usize = 64 * 1024; /// Workspace root metadata filename. -const WORKSPACE_METADATA_FILE: &str = ".onyx-workspace.json"; +pub(crate) const WORKSPACE_METADATA_FILE: &str = ".onyx-workspace.json"; /// Per-list metadata filename. -const LIST_METADATA_FILE: &str = ".listdata.json"; +pub(crate) const LIST_METADATA_FILE: &str = ".listdata.json"; /// Task file extension. const TASK_FILE_EXT: &str = "md"; /// Default version for tasks without a version field (legacy files). diff --git a/crates/onyx-core/src/sync.rs b/crates/onyx-core/src/sync.rs index 457e1a3..1fe4f82 100644 --- a/crates/onyx-core/src/sync.rs +++ b/crates/onyx-core/src/sync.rs @@ -5,7 +5,10 @@ use serde::{Deserialize, Serialize}; use sha2::{Sha256, Digest}; use uuid::Uuid; use crate::error::{Error, Result}; -use crate::storage::{atomic_write, ListMetadata, TaskFrontmatter}; +use crate::storage::{ + atomic_write, ListMetadata, TaskFrontmatter, LIST_METADATA_FILE, MAX_FRONTMATTER_LENGTH, + WORKSPACE_METADATA_FILE, +}; use crate::webdav::WebDavClient; /// File-based lock to prevent concurrent sync operations on the same workspace. @@ -404,11 +407,6 @@ pub fn compute_checksum(data: &[u8]) -> String { format!("{:x}", hasher.finalize()) } -/// Workspace root metadata filename. -const WORKSPACE_METADATA_FILE: &str = ".onyx-workspace.json"; -/// Per-list metadata filename. -const LIST_METADATA_FILE: &str = ".listdata.json"; - /// Check if a file is syncable: *.md files and metadata files at expected depths. fn is_syncable(path: &str) -> bool { let parts: Vec<&str> = path.split('/').collect(); @@ -862,10 +860,11 @@ fn parse_frontmatter_for_conflict(content: &str) -> Result<(TaskFrontmatter, Str .ok_or_else(|| Error::InvalidData("Missing closing frontmatter delimiter".to_string()))?; let frontmatter_str = lines[1..=end_idx].join("\n"); // Reject oversized frontmatter to prevent DoS via crafted YAML - if frontmatter_str.len() > 64 * 1024 { + if frontmatter_str.len() > MAX_FRONTMATTER_LENGTH { return Err(Error::InvalidData(format!( - "Frontmatter too large ({} bytes, max 65536)", - frontmatter_str.len() + "Frontmatter too large ({} bytes, max {})", + frontmatter_str.len(), + MAX_FRONTMATTER_LENGTH ))); } let frontmatter: TaskFrontmatter = serde_yaml::from_str(&frontmatter_str)