Show More
@@ -228,7 +228,7 b" impl<'on_disk> DirstateMap<'on_disk> {" | |||
|
228 | 228 | pub fn new_v2( |
|
229 | 229 | on_disk: &'on_disk [u8], |
|
230 | 230 | ) -> Result<(Self, Option<DirstateParents>), DirstateError> { |
|
231 | on_disk::read(on_disk) | |
|
231 | Ok(on_disk::read(on_disk)?) | |
|
232 | 232 | } |
|
233 | 233 | |
|
234 | 234 | #[timed] |
@@ -108,14 +108,32 b' fn _static_assert_size_of() {' | |||
|
108 | 108 | let _ = std::mem::transmute::<Node, [u8; 57]>; |
|
109 | 109 | } |
|
110 | 110 | |
|
111 | /// Unexpected file format found in `.hg/dirstate` with the "v2" format. | |
|
112 | pub(crate) struct DirstateV2ParseError; | |
|
113 | ||
|
114 | impl From<DirstateV2ParseError> for HgError { | |
|
115 | fn from(_: DirstateV2ParseError) -> Self { | |
|
116 | HgError::corrupted("dirstate-v2 parse error") | |
|
117 | } | |
|
118 | } | |
|
119 | ||
|
120 | impl From<DirstateV2ParseError> for crate::DirstateError { | |
|
121 | fn from(error: DirstateV2ParseError) -> Self { | |
|
122 | HgError::from(error).into() | |
|
123 | } | |
|
124 | } | |
|
125 | ||
|
111 | 126 | pub(super) fn read<'on_disk>( |
|
112 | 127 | on_disk: &'on_disk [u8], |
|
113 | ) -> Result<(DirstateMap<'on_disk>, Option<DirstateParents>), DirstateError> { | |
|
128 | ) -> Result< | |
|
129 | (DirstateMap<'on_disk>, Option<DirstateParents>), | |
|
130 | DirstateV2ParseError, | |
|
131 | > { | |
|
114 | 132 | if on_disk.is_empty() { |
|
115 | 133 | return Ok((DirstateMap::empty(on_disk), None)); |
|
116 | 134 | } |
|
117 |
let (header, _) = |
|
|
118 | .map_err(|_| HgError::corrupted("truncated dirstate-v2"))?; | |
|
135 | let (header, _) = | |
|
136 | Header::from_bytes(on_disk).map_err(|_| DirstateV2ParseError)?; | |
|
119 | 137 | let Header { |
|
120 | 138 | marker, |
|
121 | 139 | parents, |
@@ -124,7 +142,7 b" pub(super) fn read<'on_disk>(" | |||
|
124 | 142 | nodes_with_copy_source_count, |
|
125 | 143 | } = header; |
|
126 | 144 | if marker != V2_FORMAT_MARKER { |
|
127 | return Err(HgError::corrupted("missing dirstated-v2 marker").into()); | |
|
145 | return Err(DirstateV2ParseError); | |
|
128 | 146 | } |
|
129 | 147 | let dirstate_map = DirstateMap { |
|
130 | 148 | on_disk, |
@@ -140,7 +158,7 b' impl Node {' | |||
|
140 | 158 | pub(super) fn path<'on_disk>( |
|
141 | 159 | &self, |
|
142 | 160 | on_disk: &'on_disk [u8], |
|
143 |
) -> Result<dirstate_map::NodeKey<'on_disk>, |
|
|
161 | ) -> Result<dirstate_map::NodeKey<'on_disk>, DirstateV2ParseError> { | |
|
144 | 162 | let full_path = read_hg_path(on_disk, self.full_path)?; |
|
145 | 163 | let base_name_start = usize::try_from(self.base_name_start.get()) |
|
146 | 164 | // u32 -> usize, could only panic on a 16-bit CPU |
@@ -148,16 +166,14 b' impl Node {' | |||
|
148 | 166 | if base_name_start < full_path.len() { |
|
149 | 167 | Ok(WithBasename::from_raw_parts(full_path, base_name_start)) |
|
150 | 168 | } else { |
|
151 | Err(HgError::corrupted( | |
|
152 | "dirstate-v2 base_name_start out of bounds", | |
|
153 | )) | |
|
169 | Err(DirstateV2ParseError) | |
|
154 | 170 | } |
|
155 | 171 | } |
|
156 | 172 | |
|
157 | 173 | pub(super) fn copy_source<'on_disk>( |
|
158 | 174 | &self, |
|
159 | 175 | on_disk: &'on_disk [u8], |
|
160 |
) -> Result<Option<Cow<'on_disk, HgPath>>, |
|
|
176 | ) -> Result<Option<Cow<'on_disk, HgPath>>, DirstateV2ParseError> { | |
|
161 | 177 | Ok(if self.copy_source.start.get() != 0 { |
|
162 | 178 | Some(read_hg_path(on_disk, self.copy_source)?) |
|
163 | 179 | } else { |
@@ -165,10 +181,16 b' impl Node {' | |||
|
165 | 181 | }) |
|
166 | 182 | } |
|
167 | 183 | |
|
168 | pub(super) fn entry(&self) -> Result<Option<DirstateEntry>, HgError> { | |
|
184 | pub(super) fn entry( | |
|
185 | &self, | |
|
186 | ) -> Result<Option<DirstateEntry>, DirstateV2ParseError> { | |
|
169 | 187 | Ok(if self.entry.state != b'\0' { |
|
170 | 188 | Some(DirstateEntry { |
|
171 |
state: self |
|
|
189 | state: self | |
|
190 | .entry | |
|
191 | .state | |
|
192 | .try_into() | |
|
193 | .map_err(|_| DirstateV2ParseError)?, | |
|
172 | 194 | mode: self.entry.mode.get(), |
|
173 | 195 | mtime: self.entry.mtime.get(), |
|
174 | 196 | size: self.entry.size.get(), |
@@ -181,7 +203,7 b' impl Node {' | |||
|
181 | 203 | pub(super) fn to_in_memory_node<'on_disk>( |
|
182 | 204 | &self, |
|
183 | 205 | on_disk: &'on_disk [u8], |
|
184 |
) -> Result<dirstate_map::Node<'on_disk>, |
|
|
206 | ) -> Result<dirstate_map::Node<'on_disk>, DirstateV2ParseError> { | |
|
185 | 207 | Ok(dirstate_map::Node { |
|
186 | 208 | children: read_nodes(on_disk, self.children)?, |
|
187 | 209 | copy_source: self.copy_source(on_disk)?, |
@@ -194,7 +216,7 b' impl Node {' | |||
|
194 | 216 | fn read_nodes( |
|
195 | 217 | on_disk: &[u8], |
|
196 | 218 | slice: ChildNodes, |
|
197 |
) -> Result<dirstate_map::ChildNodes, |
|
|
219 | ) -> Result<dirstate_map::ChildNodes, DirstateV2ParseError> { | |
|
198 | 220 | read_slice::<Node>(on_disk, slice)? |
|
199 | 221 | .iter() |
|
200 | 222 | .map(|node| { |
@@ -204,12 +226,18 b' fn read_nodes(' | |||
|
204 | 226 | .map(dirstate_map::ChildNodes::InMemory) |
|
205 | 227 | } |
|
206 | 228 | |
|
207 | fn read_hg_path(on_disk: &[u8], slice: Slice) -> Result<Cow<HgPath>, HgError> { | |
|
229 | fn read_hg_path( | |
|
230 | on_disk: &[u8], | |
|
231 | slice: Slice, | |
|
232 | ) -> Result<Cow<HgPath>, DirstateV2ParseError> { | |
|
208 | 233 | let bytes = read_slice::<u8>(on_disk, slice)?; |
|
209 | 234 | Ok(Cow::Borrowed(HgPath::new(bytes))) |
|
210 | 235 | } |
|
211 | 236 | |
|
212 | fn read_slice<T>(on_disk: &[u8], slice: Slice) -> Result<&[T], HgError> | |
|
237 | fn read_slice<T>( | |
|
238 | on_disk: &[u8], | |
|
239 | slice: Slice, | |
|
240 | ) -> Result<&[T], DirstateV2ParseError> | |
|
213 | 241 | where |
|
214 | 242 | T: BytesCast, |
|
215 | 243 | { |
@@ -221,9 +249,7 b' where' | |||
|
221 | 249 | .get(start..) |
|
222 | 250 | .and_then(|bytes| T::slice_from_bytes(bytes, len).ok()) |
|
223 | 251 | .map(|(slice, _rest)| slice) |
|
224 |
.ok_or_else(|| |
|
|
225 | HgError::corrupted("dirstate v2 slice is out of bounds") | |
|
226 | }) | |
|
252 | .ok_or_else(|| DirstateV2ParseError) | |
|
227 | 253 | } |
|
228 | 254 | |
|
229 | 255 | pub(super) fn write( |
General Comments 0
You need to be logged in to leave comments.
Login now