##// END OF EJS Templates
dirstate-v2: Enforce data size read from the docket file...
Simon Sapin -
r48475:48aec076 default
parent child Browse files
Show More
@@ -637,7 +637,9 b' if rustmod is not None:'
637 637 data = self._opener.read(self.docket.data_filename())
638 638 else:
639 639 data = b''
640 self._rustmap = rustmod.DirstateMap.new_v2(data)
640 self._rustmap = rustmod.DirstateMap.new_v2(
641 data, self.docket.data_size
642 )
641 643 parents = self.docket.parents
642 644 else:
643 645 self._rustmap, parents = rustmod.DirstateMap.new_v1(
@@ -410,8 +410,15 b" impl<'on_disk> DirstateMap<'on_disk> {"
410 410 }
411 411
412 412 #[timed]
413 pub fn new_v2(on_disk: &'on_disk [u8]) -> Result<Self, DirstateError> {
414 Ok(on_disk::read(on_disk)?)
413 pub fn new_v2(
414 on_disk: &'on_disk [u8],
415 data_size: usize,
416 ) -> Result<Self, DirstateError> {
417 if let Some(data) = on_disk.get(..data_size) {
418 Ok(on_disk::read(data)?)
419 } else {
420 Err(DirstateV2ParseError.into())
421 }
415 422 }
416 423
417 424 #[timed]
@@ -21,7 +21,7 b' use bytes_cast::unaligned::{I32Be, I64Be'
21 21 use bytes_cast::BytesCast;
22 22 use format_bytes::format_bytes;
23 23 use std::borrow::Cow;
24 use std::convert::TryFrom;
24 use std::convert::{TryFrom, TryInto};
25 25 use std::time::{Duration, SystemTime, UNIX_EPOCH};
26 26
27 27 /// Added at the start of `.hg/dirstate` when the "v2" format is used.
@@ -224,6 +224,11 b" impl<'on_disk> Docket<'on_disk> {"
224 224 DirstateParents { p1, p2 }
225 225 }
226 226
227 pub fn data_size(&self) -> usize {
228 // This `unwrap` could only panic on a 16-bit CPU
229 self.header.data_size.get().try_into().unwrap()
230 }
231
227 232 pub fn data_filename(&self) -> String {
228 233 String::from_utf8(format_bytes!(b"dirstate.{}.d", self.uuid)).unwrap()
229 234 }
@@ -83,11 +83,12 b' py_class!(pub class DirstateMap |py| {'
83 83 @staticmethod
84 84 def new_v2(
85 85 on_disk: PyBytes,
86 data_size: usize,
86 87 ) -> PyResult<PyObject> {
87 88 let dirstate_error = |e: DirstateError| {
88 89 PyErr::new::<exc::OSError, _>(py, format!("Dirstate error: {:?}", e))
89 90 };
90 let inner = OwningDirstateMap::new_v2(py, on_disk)
91 let inner = OwningDirstateMap::new_v2(py, on_disk, data_size)
91 92 .map_err(dirstate_error)?;
92 93 let map = Self::create_instance(py, Box::new(inner))?;
93 94 Ok(map.into_object())
@@ -48,9 +48,10 b' impl OwningDirstateMap {'
48 48 pub fn new_v2(
49 49 py: Python,
50 50 on_disk: PyBytes,
51 data_size: usize,
51 52 ) -> Result<Self, DirstateError> {
52 53 let bytes: &'_ [u8] = on_disk.data(py);
53 let map = DirstateMap::new_v2(bytes)?;
54 let map = DirstateMap::new_v2(bytes, data_size)?;
54 55
55 56 // Like in `bytes` above, this `'_` lifetime parameter borrows from
56 57 // the bytes buffer owned by `on_disk`.
@@ -170,11 +170,13 b' pub fn run(invocation: &crate::CliInvoca'
170 170 let (mut dmap, parents) = if repo.has_dirstate_v2() {
171 171 let parents;
172 172 let dirstate_data;
173 let data_size;
173 174 if let Some(docket_data) =
174 175 repo.hg_vfs().read("dirstate").io_not_found_as_none()?
175 176 {
176 177 let docket = on_disk::read_docket(&docket_data)?;
177 178 parents = Some(docket.parents());
179 data_size = docket.data_size();
178 180 dirstate_data_mmap = repo
179 181 .hg_vfs()
180 182 .mmap_open(docket.data_filename())
@@ -182,9 +184,10 b' pub fn run(invocation: &crate::CliInvoca'
182 184 dirstate_data = dirstate_data_mmap.as_deref().unwrap_or(b"");
183 185 } else {
184 186 parents = None;
187 data_size = 0;
185 188 dirstate_data = b"";
186 189 }
187 let dmap = DirstateMap::new_v2(dirstate_data)?;
190 let dmap = DirstateMap::new_v2(dirstate_data, data_size)?;
188 191 (dmap, parents)
189 192 } else {
190 193 dirstate_data_mmap =
General Comments 0
You need to be logged in to leave comments. Login now