##// END OF EJS Templates
rust-nodemap: backed out mitigation for issue 6554...
Georges Racinet -
r49090:aa88fb60 stable
parent child Browse files
Show More
@@ -59,22 +59,12 b' py_class!(pub class MixedIndex |py| {'
59
59
60 /// Return Revision if found, raises a bare `error.RevlogError`
60 /// Return Revision if found, raises a bare `error.RevlogError`
61 /// in case of ambiguity, same as C version does
61 /// in case of ambiguity, same as C version does
62 def get_rev(&self, pynode: PyBytes) -> PyResult<Option<Revision>> {
62 def get_rev(&self, node: PyBytes) -> PyResult<Option<Revision>> {
63 let opt = self.get_nodetree(py)?.borrow();
63 let opt = self.get_nodetree(py)?.borrow();
64 let nt = opt.as_ref().unwrap();
64 let nt = opt.as_ref().unwrap();
65 let idx = &*self.cindex(py).borrow();
65 let idx = &*self.cindex(py).borrow();
66 let node = node_from_py_bytes(py, &pynode)?;
66 let node = node_from_py_bytes(py, &node)?;
67 match nt.find_bin(idx, node.into())
67 nt.find_bin(idx, node.into()).map_err(|e| nodemap_error(py, e))
68 {
69 Ok(None) =>
70 // fallback to C implementation, remove once
71 // https://bz.mercurial-scm.org/show_bug.cgi?id=6554
72 // is fixed (a simple backout should do)
73 self.call_cindex(py, "get_rev", &PyTuple::new(py, &[pynode.into_object()]), None)?
74 .extract(py),
75 Ok(Some(rev)) => Ok(Some(rev)),
76 Err(e) => Err(nodemap_error(py, e)),
77 }
78 }
68 }
79
69
80 /// same as `get_rev()` but raises a bare `error.RevlogError` if node
70 /// same as `get_rev()` but raises a bare `error.RevlogError` if node
@@ -104,34 +94,27 b' py_class!(pub class MixedIndex |py| {'
104 }
94 }
105 }
95 }
106
96
107 def partialmatch(&self, pynode: PyObject) -> PyResult<Option<PyBytes>> {
97 def partialmatch(&self, node: PyObject) -> PyResult<Option<PyBytes>> {
108 let opt = self.get_nodetree(py)?.borrow();
98 let opt = self.get_nodetree(py)?.borrow();
109 let nt = opt.as_ref().unwrap();
99 let nt = opt.as_ref().unwrap();
110 let idx = &*self.cindex(py).borrow();
100 let idx = &*self.cindex(py).borrow();
111
101
112 let node_as_string = if cfg!(feature = "python3-sys") {
102 let node_as_string = if cfg!(feature = "python3-sys") {
113 pynode.cast_as::<PyString>(py)?.to_string(py)?.to_string()
103 node.cast_as::<PyString>(py)?.to_string(py)?.to_string()
114 }
104 }
115 else {
105 else {
116 let node = pynode.extract::<PyBytes>(py)?;
106 let node = node.extract::<PyBytes>(py)?;
117 String::from_utf8_lossy(node.data(py)).to_string()
107 String::from_utf8_lossy(node.data(py)).to_string()
118 };
108 };
119
109
120 let prefix = NodePrefix::from_hex(&node_as_string).map_err(|_| PyErr::new::<ValueError, _>(py, "Invalid node or prefix"))?;
110 let prefix = NodePrefix::from_hex(&node_as_string).map_err(|_| PyErr::new::<ValueError, _>(py, "Invalid node or prefix"))?;
121
111
122 match nt.find_bin(idx, prefix) {
112 nt.find_bin(idx, prefix)
123 Ok(None) =>
113 // TODO make an inner API returning the node directly
124 // fallback to C implementation, remove once
114 .map(|opt| opt.map(
125 // https://bz.mercurial-scm.org/show_bug.cgi?id=6554
115 |rev| PyBytes::new(py, idx.node(rev).unwrap().as_bytes())))
126 // is fixed (a simple backout should do)
116 .map_err(|e| nodemap_error(py, e))
127 self.call_cindex(
117
128 py, "partialmatch",
129 &PyTuple::new(py, &[pynode]), None
130 )?.extract(py),
131 Ok(Some(rev)) =>
132 Ok(Some(PyBytes::new(py, idx.node(rev).unwrap().as_bytes()))),
133 Err(e) => Err(nodemap_error(py, e)),
134 }
135 }
118 }
136
119
137 /// append an index entry
120 /// append an index entry
@@ -435,46 +435,6 b" mercurial don't crash"
435 data-length: 121088
435 data-length: 121088
436 data-unused: 0
436 data-unused: 0
437 data-unused: 0.000%
437 data-unused: 0.000%
438
439 Sub-case: fallback for corrupted data file
440 ------------------------------------------
441
442 Sabotaging the data file so that nodemap resolutions fail, triggering fallback to
443 (non-persistent) C implementation.
444
445
446 $ UUID=`hg debugnodemap --metadata| grep 'uid:' | \
447 > sed 's/uid: //'`
448 $ FILE=.hg/store/00changelog-"${UUID}".nd
449 $ python -c "fobj = open('$FILE', 'r+b'); fobj.write(b'\xff' * 121088); fobj.close()"
450
451 The nodemap data file is still considered in sync with the docket. This
452 would fail without the fallback to the (non-persistent) C implementation:
453
454 $ hg log -r b355ef8adce0949b8bdf6afc72ca853740d65944 -T '{rev}\n' --traceback
455 5002
456
457 The nodemap data file hasn't been fixed, more tests can be inserted:
458
459 $ hg debugnodemap --dump-disk | f --bytes=256 --hexdump --size
460 size=121088
461 0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
462 0010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
463 0020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
464 0030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
465 0040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
466 0050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
467 0060: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
468 0070: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
469 0080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
470 0090: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
471 00a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
472 00b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
473 00c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
474 00d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
475 00e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
476 00f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
477
478 $ mv ../tmp-data-file $FILE
438 $ mv ../tmp-data-file $FILE
479 $ mv ../tmp-docket .hg/store/00changelog.n
439 $ mv ../tmp-docket .hg/store/00changelog.n
480
440
General Comments 0
You need to be logged in to leave comments. Login now