From c59e1cf89c147ce6af7ec1e145813f806bc461da Mon Sep 17 00:00:00 2001 From: Ricardo Koller Date: Sat, 21 Apr 2018 10:44:25 -0400 Subject: [PATCH] Handle special dot and dotdot files --- src/fat_fs.ml | 7 ++++++- src/fat_name.ml | 40 ++++++++++++++++++++++++++++------------ src/fat_name.mli | 2 ++ 3 files changed, 36 insertions(+), 13 deletions(-) diff --git a/src/fat_fs.ml b/src/fat_fs.ml index 956b488..4087ae7 100644 --- a/src/fat_fs.ml +++ b/src/fat_fs.ml @@ -207,7 +207,8 @@ module Make (B: Mirage_block_lwt.S) = struct (sectors_of_file fs f) (** [find device fs path] returns a [find_result] corresponding to - the object stored at [path] *) + the object stored at [path] + XXX: doesn't handle the cases where path is: /a/../b or /a/./b *) let find device fs path = let readdir = function | Dir ds -> Lwt.return (Ok ds) @@ -219,6 +220,10 @@ module Make (B: Mirage_block_lwt.S) = struct | [] -> (match current with | Dir ds -> Lwt.return (Ok (Dir ds)) + | File ({Fat_name.dos = _, {Fat_name.is_dot = true; _}; _} as d) -> + Lwt.return (Ok (File d)) + | File ({Fat_name.dos = _, {Fat_name.is_dotdot = true; _}; _} as d) -> + Lwt.return (Ok (File d)) | File {Fat_name.dos = _, {Fat_name.subdir = true; _}; _} -> readdir current >|*= fun names -> Ok (Dir names) diff --git a/src/fat_name.ml b/src/fat_name.ml index 8d6628e..8eab89f 100644 --- a/src/fat_name.ml +++ b/src/fat_name.ml @@ -54,6 +54,8 @@ type dos = { modify: datetime; start_cluster: int; file_size: int32; + is_dot: bool; + is_dotdot: bool; } (** Useful for streaming entries to/from the disk *) @@ -77,18 +79,20 @@ let fake_root_entry = { dos = 0, { filename = ""; ext = ""; deleted = false; read_only = false; hidden = false; system = false; volume = false; subdir = true; archive = false; - create = epoch; access = epoch; modify = epoch; start_cluster = 0; file_size = 0l + create = epoch; access = epoch; modify = epoch; start_cluster = 0; file_size = 0l; + is_dot = false; is_dotdot = false; }; lfns = [] } +let is_dot filename = + filename = "." + +let is_dotdot filename = + filename = ".." + let remove_padding x = - let rec inner = function - | -1 -> x - | n when x.[n] = ' ' -> inner (n-1) - | n -> String.sub x 0 (n + 1) - in - inner (String.length x - 1) + String.trim x let file_size_of r = (snd r.dos).file_size let deleted r = (snd r.dos).deleted @@ -97,7 +101,9 @@ let filename_of r = then r.utf_filename else let d = snd(r.dos) in - (remove_padding d.filename) ^ "." ^ (remove_padding d.ext) + let ext = (remove_padding d.ext) in + let filename = (remove_padding d.filename) in + if ext = "" then filename else filename ^ "." ^ ext let to_single_entries r = List.rev ((Dos (snd r.dos)) :: (List.map (fun l -> Lfn (snd l)) r.lfns)) @@ -119,7 +125,9 @@ let legal_dos_string x = with Not_found -> false let dot = Re.Str.regexp_string "." -let is_legal_dos_name filename = match Re.Str.split dot filename with +let is_legal_dos_name filename = + if (is_dot filename || is_dotdot filename) then true else + match Re.Str.split dot filename with | [ one ] -> String.length one <= 8 && (legal_dos_string one) | [ one; two ] -> String.length one <= 8 && (String.length two <= 3) @@ -137,6 +145,7 @@ let add_padding p n x = let uppercase = Astring.String.Ascii.uppercase let dos_name_of_filename filename = + if (is_dot filename || is_dotdot filename) then filename, "" else if is_legal_dos_name filename then match Re.Str.split dot filename with | [ one ] -> add_padding ' ' 8 one, " " @@ -200,7 +209,9 @@ let make ?(read_only=false) ?(system=false) ?(subdir=false) filename = access = epoch; modify = epoch; start_cluster = start_cluster; - file_size = file_size + file_size = file_size; + is_dot = false; + is_dotdot = false } in let checksum = compute_checksum dos in let lfns = @@ -252,7 +263,10 @@ let to_string x = let d = snd x.dos in let y = trim_utf16 x.utf_filename in let z = utf16_to_ascii y in - if z = "" then d.filename ^ "." ^ d.ext else z + let ext = (remove_padding d.ext) in + let filename = (remove_padding d.filename) in + if z = "" && ext = "" then filename else + if z = "" then filename ^ "." ^ ext else z let int_to_hms time = let hours = ((time lsr 11) land 0b11111) in @@ -375,7 +389,9 @@ let unmarshal buf = access = time_of_int last_access_date 0 0; modify = time_of_int last_modify_date last_modify_time 0; start_cluster = start_cluster; - file_size = file_size + file_size = file_size; + is_dot = (is_dot (remove_padding (Bytes.to_string filename))); + is_dotdot = (is_dotdot (remove_padding (Bytes.to_string filename))); } end diff --git a/src/fat_name.mli b/src/fat_name.mli index 3cccfac..26cbc75 100644 --- a/src/fat_name.mli +++ b/src/fat_name.mli @@ -50,6 +50,8 @@ type dos = { modify: datetime; start_cluster: int; file_size: int32; + is_dot: bool; + is_dotdot: bool; } (** A DOS disk entry *)