##// END OF EJS Templates
rust-revlog: fix incorrect results with NULL_NODE prefixes...
Georges Racinet -
r51637:bca40373 stable
parent child Browse files
Show More
@@ -225,16 +225,23 b' impl Revlog {'
225 &self,
225 &self,
226 node: NodePrefix,
226 node: NodePrefix,
227 ) -> Result<Revision, RevlogError> {
227 ) -> Result<Revision, RevlogError> {
228 if node.is_prefix_of(&NULL_NODE) {
228 let looked_up = if let Some(nodemap) = &self.nodemap {
229 return Ok(NULL_REVISION);
229 nodemap
230 }
230 .find_bin(&self.index, node)?
231 .ok_or(RevlogError::InvalidRevision)
232 } else {
233 self.rev_from_node_no_persistent_nodemap(node)
234 };
231
235
232 if let Some(nodemap) = &self.nodemap {
236 if node.is_prefix_of(&NULL_NODE) {
233 return nodemap
237 return match looked_up {
234 .find_bin(&self.index, node)?
238 Ok(_) => Err(RevlogError::AmbiguousPrefix),
235 .ok_or(RevlogError::InvalidRevision);
239 Err(RevlogError::InvalidRevision) => Ok(NULL_REVISION),
236 }
240 res => res,
237 self.rev_from_node_no_persistent_nodemap(node)
241 };
242 };
243
244 looked_up
238 }
245 }
239
246
240 /// Same as `rev_from_node`, without using a persistent nodemap
247 /// Same as `rev_from_node`, without using a persistent nodemap
@@ -677,6 +684,7 b' mod tests {'
677 assert_eq!(revlog.len(), 0);
684 assert_eq!(revlog.len(), 0);
678 assert!(revlog.get_entry(0).is_err());
685 assert!(revlog.get_entry(0).is_err());
679 assert!(!revlog.has_rev(0));
686 assert!(!revlog.has_rev(0));
687 assert_eq!(revlog.rev_from_node(NULL_NODE.into()).unwrap(), -1);
680 }
688 }
681
689
682 #[test]
690 #[test]
@@ -748,4 +756,65 b' mod tests {'
748 assert!(p2_entry.is_some());
756 assert!(p2_entry.is_some());
749 assert_eq!(p2_entry.unwrap().revision(), 1);
757 assert_eq!(p2_entry.unwrap().revision(), 1);
750 }
758 }
759
760 #[test]
761 fn test_nodemap() {
762 let temp = tempfile::tempdir().unwrap();
763 let vfs = Vfs { base: temp.path() };
764
765 // building a revlog with a forced Node starting with zeros
766 // This is a corruption, but it does not preclude using the nodemap
767 // if we don't try and access the data
768 let node0 = Node::from_hex("00d2a3912a0b24502043eae84ee4b279c18b90dd")
769 .unwrap();
770 let node1 = Node::from_hex("b004912a8510032a0350a74daa2803dadfb00e12")
771 .unwrap();
772 let entry0_bytes = IndexEntryBuilder::new()
773 .is_first(true)
774 .with_version(1)
775 .with_inline(true)
776 .with_offset(INDEX_ENTRY_SIZE)
777 .with_node(node0)
778 .build();
779 let entry1_bytes = IndexEntryBuilder::new()
780 .with_offset(INDEX_ENTRY_SIZE)
781 .with_node(node1)
782 .build();
783 let contents = vec![entry0_bytes, entry1_bytes]
784 .into_iter()
785 .flatten()
786 .collect_vec();
787 std::fs::write(temp.path().join("foo.i"), contents).unwrap();
788 let revlog = Revlog::open(&vfs, "foo.i", None, false).unwrap();
789
790 // accessing the data shows the corruption
791 revlog.get_entry(0).unwrap().data().unwrap_err();
792
793 assert_eq!(revlog.rev_from_node(NULL_NODE.into()).unwrap(), -1);
794 assert_eq!(revlog.rev_from_node(node0.into()).unwrap(), 0);
795 assert_eq!(revlog.rev_from_node(node1.into()).unwrap(), 1);
796 assert_eq!(
797 revlog
798 .rev_from_node(NodePrefix::from_hex("000").unwrap())
799 .unwrap(),
800 -1
801 );
802 assert_eq!(
803 revlog
804 .rev_from_node(NodePrefix::from_hex("b00").unwrap())
805 .unwrap(),
806 1
807 );
808 // RevlogError does not implement PartialEq
809 // (ultimately because io::Error does not)
810 match revlog
811 .rev_from_node(NodePrefix::from_hex("00").unwrap())
812 .expect_err("Expected to give AmbiguousPrefix error")
813 {
814 RevlogError::AmbiguousPrefix => (),
815 e => {
816 panic!("Got another error than AmbiguousPrefix: {:?}", e);
751 }
817 }
818 };
819 }
820 }
General Comments 0
You need to be logged in to leave comments. Login now