From 0360bbe4aa32483c488620a35f6b5a949c3f33e4 Mon Sep 17 00:00:00 2001 From: imxyy_soope_ Date: Sat, 31 Jan 2026 17:02:11 +0800 Subject: [PATCH] fix: canonicalize paths --- nix-js/runtime-ts/src/path.ts | 33 ++++++++++++++++++++++++++++++++- nix-js/src/nix_hash.rs | 6 ++---- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/nix-js/runtime-ts/src/path.ts b/nix-js/runtime-ts/src/path.ts index 1ed13dd..583850d 100644 --- a/nix-js/runtime-ts/src/path.ts +++ b/nix-js/runtime-ts/src/path.ts @@ -1,7 +1,38 @@ import { IS_PATH, type NixPath } from "./types"; +const canonicalizePath = (path: string): string => { + const parts: string[] = []; + let i = 0; + const len = path.length; + + while (i < len) { + while (i < len && path[i] === "/") i++; + if (i >= len) break; + + let j = i; + while (j < len && path[j] !== "/") j++; + const component = path.slice(i, j); + i = j; + + if (component === ".") { + continue; + } else if (component === "..") { + if (parts.length > 0) { + parts.pop(); + } + } else { + parts.push(component); + } + } + + if (parts.length === 0) { + return "/"; + } + return "/" + parts.join("/"); +}; + export const mkPath = (value: string): NixPath => { - return { [IS_PATH]: true, value }; + return { [IS_PATH]: true, value: canonicalizePath(value) }; }; export const getPathValue = (p: NixPath): string => { diff --git a/nix-js/src/nix_hash.rs b/nix-js/src/nix_hash.rs index 908da25..558602d 100644 --- a/nix-js/src/nix_hash.rs +++ b/nix-js/src/nix_hash.rs @@ -62,12 +62,10 @@ pub fn nix_base32_decode(input: &str) -> Option> { } pub fn decode_hash_to_hex(hash_str: &str) -> Option { - if hash_str.starts_with("sha256:") { - let rest = &hash_str[7..]; + if let Some(rest) = hash_str.strip_prefix("sha256:") { return decode_hash_to_hex(rest); } - if hash_str.starts_with("sha256-") { - let base64_str = &hash_str[7..]; + if let Some(base64_str) = hash_str.strip_prefix("sha256-") { use base64::{Engine, engine::general_purpose::STANDARD}; let bytes = STANDARD.decode(base64_str).ok()?; return Some(hex::encode(bytes));