From cbb753d18afb6ea18f8014f836903d9b7f6c6162 Mon Sep 17 00:00:00 2001 From: "benjamin.747" Date: Thu, 2 Jan 2025 14:21:07 +0800 Subject: [PATCH] fix #790 --- Cargo.toml | 9 ++++---- mercury/Cargo.toml | 1 + mercury/src/internal/object/tree.rs | 33 ++++++++++++++++++++--------- 3 files changed, 29 insertions(+), 14 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 34c16196..6fa2ee91 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -61,19 +61,19 @@ futures-util = "0.3.30" go-defer = "0.1.0" russh = "0.49.0" russh-keys = "0.49.1" -axum = "0.7.7" -axum-extra = "0.9.4" +axum = "0.7.9" +axum-extra = "0.9.6" axum-server = "0.7.1" tower-http = "0.6.1" tower = "0.5.1" hex = "0.4.3" -sea-orm = "1.1.1" +sea-orm = "1.1.3" flate2 = "1.0.35" bstr = "1.11.0" colored = "2.1.0" idgenerator = "2.0.0" num_cpus = "1.16.0" -config = "0.15.0" +config = "0.15.4" shadow-rs = "0.36.0" reqwest = "0.12.9" lazy_static = "1.5.0" @@ -89,6 +89,7 @@ cedar-policy = "4.2.2" secp256k1 = "0.30.0" oauth2 = "4.4.2" base64 = "0.22.1" +encoding_rs = "0.8.31" [profile.release] debug = true \ No newline at end of file diff --git a/mercury/Cargo.toml b/mercury/Cargo.toml index dca858a3..e4952ec1 100644 --- a/mercury/Cargo.toml +++ b/mercury/Cargo.toml @@ -34,6 +34,7 @@ futures-util = { workspace = true } bytes = { workspace = true } axum = { workspace = true } memchr = { workspace = true } +encoding_rs = { workspace = true } rayon = "1.10.0" [target.'cfg(windows)'.dependencies] # only on Windows diff --git a/mercury/src/internal/object/tree.rs b/mercury/src/internal/object/tree.rs index 3f947320..a20832a1 100644 --- a/mercury/src/internal/object/tree.rs +++ b/mercury/src/internal/object/tree.rs @@ -14,15 +14,15 @@ //! have been added, modified, or deleted between two points in time. This allows Git to perform //! operations like merging and rebasing more quickly and accurately. //! -use std::fmt::Display; -use colored::Colorize; -use serde::Deserialize; -use serde::Serialize; use crate::errors::GitError; use crate::hash::SHA1; use crate::internal::object::ObjectTrait; use crate::internal::object::ObjectType; - +use colored::Colorize; +use encoding_rs::GBK; +use serde::Deserialize; +use serde::Serialize; +use std::fmt::Display; /// In Git, the mode field in a tree object's entry specifies the type of the object represented by /// that entry. The mode is a three-digit octal number that encodes both the permissions and the @@ -180,13 +180,26 @@ impl TreeItem { let mode = parts.next().unwrap(); let rest = parts.next().unwrap(); let mut parts = rest.splitn(2, |b| *b == b'\0'); - let name = parts.next().unwrap(); + let raw_name = parts.next().unwrap(); let id = parts.next().unwrap(); + let name = if String::from_utf8(raw_name.to_vec()).is_ok() { + String::from_utf8(raw_name.to_vec()).unwrap() + } else { + let (decoded, _, had_errors) = GBK.decode(raw_name); + if had_errors { + return Err(GitError::InvalidTreeItem(format!( + "Unsupported raw format: {:?}", + raw_name + ))); + } else { + decoded.to_string() + } + }; Ok(TreeItem { mode: TreeItemMode::tree_item_type_from_bytes(mode)?, id: SHA1::from_bytes(id), - name: String::from_utf8(name.to_vec())?, + name: name, }) } @@ -262,7 +275,7 @@ impl Tree { } /// After the subdirectory is changed, the hash value of the tree is recalculated. - pub fn rehash(&mut self){ + pub fn rehash(&mut self) { let mut data = Vec::new(); for item in &self.tree_items { data.extend_from_slice(item.to_data().as_slice()); @@ -271,9 +284,9 @@ impl Tree { } } -impl TryFrom<&[u8]> for Tree{ +impl TryFrom<&[u8]> for Tree { type Error = GitError; - fn try_from(data: &[u8]) -> Result { + fn try_from(data: &[u8]) -> Result { let h = SHA1::from_type_and_data(ObjectType::Tree, data); Tree::from_bytes(data, h) }