Show More
@@ -42,6 +42,9 b' pub enum HgError {' | |||||
42 | /// and syntax of each value. |
|
42 | /// and syntax of each value. | |
43 | #[from] |
|
43 | #[from] | |
44 | ConfigValueParseError(ConfigValueParseError), |
|
44 | ConfigValueParseError(ConfigValueParseError), | |
|
45 | ||||
|
46 | /// Censored revision data. | |||
|
47 | CensoredNodeError, | |||
45 | } |
|
48 | } | |
46 |
|
49 | |||
47 | /// Details about where an I/O error happened |
|
50 | /// Details about where an I/O error happened | |
@@ -101,6 +104,9 b' impl fmt::Display for HgError {' | |||||
101 | HgError::UnsupportedFeature(explanation) => { |
|
104 | HgError::UnsupportedFeature(explanation) => { | |
102 | write!(f, "unsupported feature: {}", explanation) |
|
105 | write!(f, "unsupported feature: {}", explanation) | |
103 | } |
|
106 | } | |
|
107 | HgError::CensoredNodeError => { | |||
|
108 | write!(f, "encountered a censored node") | |||
|
109 | } | |||
104 | HgError::ConfigValueParseError(error) => error.fmt(f), |
|
110 | HgError::ConfigValueParseError(error) => error.fmt(f), | |
105 | } |
|
111 | } | |
106 | } |
|
112 | } |
@@ -95,7 +95,7 b" impl FilelogEntry<'_> {" | |||||
95 | // Letβs call `file_data_len` what would be returned by |
|
95 | // Letβs call `file_data_len` what would be returned by | |
96 | // `self.data().file_data().len()`. |
|
96 | // `self.data().file_data().len()`. | |
97 |
|
97 | |||
98 |
if self.0.is_cen |
|
98 | if self.0.is_censored() { | |
99 | let file_data_len = 0; |
|
99 | let file_data_len = 0; | |
100 | return other_len != file_data_len; |
|
100 | return other_len != file_data_len; | |
101 | } |
|
101 | } |
@@ -378,7 +378,7 b" impl<'a> RevlogEntry<'a> {" | |||||
378 | } |
|
378 | } | |
379 | } |
|
379 | } | |
380 |
|
380 | |||
381 |
pub fn is_cen |
|
381 | pub fn is_censored(&self) -> bool { | |
382 | (self.flags & REVISION_FLAG_CENSORED) != 0 |
|
382 | (self.flags & REVISION_FLAG_CENSORED) != 0 | |
383 | } |
|
383 | } | |
384 |
|
384 | |||
@@ -389,7 +389,7 b" impl<'a> RevlogEntry<'a> {" | |||||
389 | } |
|
389 | } | |
390 |
|
390 | |||
391 | /// The data for this entry, after resolving deltas if any. |
|
391 | /// The data for this entry, after resolving deltas if any. | |
392 | pub fn data(&self) -> Result<Cow<'a, [u8]>, HgError> { |
|
392 | pub fn rawdata(&self) -> Result<Cow<'a, [u8]>, HgError> { | |
393 | let mut entry = self.clone(); |
|
393 | let mut entry = self.clone(); | |
394 | let mut delta_chain = vec![]; |
|
394 | let mut delta_chain = vec![]; | |
395 |
|
395 | |||
@@ -414,6 +414,13 b" impl<'a> RevlogEntry<'a> {" | |||||
414 | Revlog::build_data_from_deltas(entry, &delta_chain)?.into() |
|
414 | Revlog::build_data_from_deltas(entry, &delta_chain)?.into() | |
415 | }; |
|
415 | }; | |
416 |
|
416 | |||
|
417 | Ok(data) | |||
|
418 | } | |||
|
419 | ||||
|
420 | fn check_data( | |||
|
421 | &self, | |||
|
422 | data: Cow<'a, [u8]>, | |||
|
423 | ) -> Result<Cow<'a, [u8]>, HgError> { | |||
417 | if self.revlog.check_hash( |
|
424 | if self.revlog.check_hash( | |
418 | self.p1, |
|
425 | self.p1, | |
419 | self.p2, |
|
426 | self.p2, | |
@@ -426,6 +433,14 b" impl<'a> RevlogEntry<'a> {" | |||||
426 | } |
|
433 | } | |
427 | } |
|
434 | } | |
428 |
|
435 | |||
|
436 | pub fn data(&self) -> Result<Cow<'a, [u8]>, HgError> { | |||
|
437 | let data = self.rawdata()?; | |||
|
438 | if self.is_censored() { | |||
|
439 | return Err(HgError::CensoredNodeError); | |||
|
440 | } | |||
|
441 | self.check_data(data) | |||
|
442 | } | |||
|
443 | ||||
429 | /// Extract the data contained in the entry. |
|
444 | /// Extract the data contained in the entry. | |
430 | /// This may be a delta. (See `is_delta`.) |
|
445 | /// This may be a delta. (See `is_delta`.) | |
431 | fn data_chunk(&self) -> Result<Cow<'a, [u8]>, HgError> { |
|
446 | fn data_chunk(&self) -> Result<Cow<'a, [u8]>, HgError> { |
@@ -73,6 +73,9 b' impl From<HgError> for CommandError {' | |||||
73 | HgError::UnsupportedFeature(message) => { |
|
73 | HgError::UnsupportedFeature(message) => { | |
74 | CommandError::unsupported(message) |
|
74 | CommandError::unsupported(message) | |
75 | } |
|
75 | } | |
|
76 | HgError::CensoredNodeError => { | |||
|
77 | CommandError::unsupported("Encountered a censored node") | |||
|
78 | } | |||
76 | HgError::Abort { |
|
79 | HgError::Abort { | |
77 | message, |
|
80 | message, | |
78 | detailed_exit_code, |
|
81 | detailed_exit_code, |
@@ -10,10 +10,6 b'' | |||||
10 |
|
10 | |||
11 | #endif |
|
11 | #endif | |
12 |
|
12 | |||
13 | $ cat >> $HGRCPATH <<EOF |
|
|||
14 | > [extensions] |
|
|||
15 | > censor= |
|
|||
16 | > EOF |
|
|||
17 | $ cp $HGRCPATH $HGRCPATH.orig |
|
13 | $ cp $HGRCPATH $HGRCPATH.orig | |
18 |
|
14 | |||
19 | Create repo with unimpeachable content |
|
15 | Create repo with unimpeachable content | |
@@ -81,7 +77,7 b' Censor revision with 2 offenses' | |||||
81 | (this also tests file pattern matching: path relative to cwd case) |
|
77 | (this also tests file pattern matching: path relative to cwd case) | |
82 |
|
78 | |||
83 | $ mkdir -p foo/bar/baz |
|
79 | $ mkdir -p foo/bar/baz | |
84 | $ hg --cwd foo/bar/baz censor -r $C2 -t "remove password" ../../../target |
|
80 | $ hg --config extensions.censor= --cwd foo/bar/baz censor -r $C2 -t "remove password" ../../../target | |
85 | $ hg cat -r $H1 target | head -n 10 |
|
81 | $ hg cat -r $H1 target | head -n 10 | |
86 | Tainted file is now sanitized |
|
82 | Tainted file is now sanitized | |
87 | $ hg cat -r $H2 target | head -n 10 |
|
83 | $ hg cat -r $H2 target | head -n 10 | |
@@ -99,7 +95,7 b' Censor revision with 1 offense' | |||||
99 |
|
95 | |||
100 | (this also tests file pattern matching: with 'path:' scheme) |
|
96 | (this also tests file pattern matching: with 'path:' scheme) | |
101 |
|
97 | |||
102 | $ hg --cwd foo/bar/baz censor -r $C1 path:target |
|
98 | $ hg --config extensions.censor= --cwd foo/bar/baz censor -r $C1 path:target | |
103 | $ hg cat -r $H1 target | head -n 10 |
|
99 | $ hg cat -r $H1 target | head -n 10 | |
104 | Tainted file is now sanitized |
|
100 | Tainted file is now sanitized | |
105 | $ hg cat -r $H2 target | head -n 10 |
|
101 | $ hg cat -r $H2 target | head -n 10 | |
@@ -242,7 +238,7 b" with the file censored, but we can't cen" | |||||
242 | $ echo 'advanced head H1' > target |
|
238 | $ echo 'advanced head H1' > target | |
243 | $ hg ci -m 'advance head H1' target |
|
239 | $ hg ci -m 'advance head H1' target | |
244 | $ H1=`hg id --debug -i` |
|
240 | $ H1=`hg id --debug -i` | |
245 | $ hg censor -r $C3 target |
|
241 | $ hg --config extensions.censor= censor -r $C3 target | |
246 | $ hg update -r $H2 |
|
242 | $ hg update -r $H2 | |
247 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
243 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
248 | $ hg merge -r $C3 |
|
244 | $ hg merge -r $C3 | |
@@ -254,14 +250,14 b' Revisions present in repository heads ma' | |||||
254 |
|
250 | |||
255 | $ hg update -C -r $H2 |
|
251 | $ hg update -C -r $H2 | |
256 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
252 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
257 | $ hg censor -r $H2 target |
|
253 | $ hg --config extensions.censor= censor -r $H2 target | |
258 | abort: cannot censor file in heads (78a8fc215e79) |
|
254 | abort: cannot censor file in heads (78a8fc215e79) | |
259 | (clean/delete and commit first) |
|
255 | (clean/delete and commit first) | |
260 | [255] |
|
256 | [255] | |
261 | $ echo 'twiddling thumbs' > bystander |
|
257 | $ echo 'twiddling thumbs' > bystander | |
262 | $ hg ci -m 'bystander commit' |
|
258 | $ hg ci -m 'bystander commit' | |
263 | $ H2=`hg id --debug -i` |
|
259 | $ H2=`hg id --debug -i` | |
264 | $ hg censor -r "$H2^" target |
|
260 | $ hg --config extensions.censor= censor -r "$H2^" target | |
265 | abort: cannot censor file in heads (efbe78065929) |
|
261 | abort: cannot censor file in heads (efbe78065929) | |
266 | (clean/delete and commit first) |
|
262 | (clean/delete and commit first) | |
267 | [255] |
|
263 | [255] | |
@@ -273,7 +269,7 b' Cannot censor working directory' | |||||
273 | $ H2=`hg id --debug -i` |
|
269 | $ H2=`hg id --debug -i` | |
274 | $ hg update -r "$H2^" |
|
270 | $ hg update -r "$H2^" | |
275 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
271 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
276 | $ hg censor -r . target |
|
272 | $ hg --config extensions.censor= censor -r . target | |
277 | abort: cannot censor working directory |
|
273 | abort: cannot censor working directory | |
278 | (clean/delete/update first) |
|
274 | (clean/delete/update first) | |
279 | [255] |
|
275 | [255] | |
@@ -286,7 +282,7 b' Can re-add file after being deleted + ce' | |||||
286 | $ hg rm target |
|
282 | $ hg rm target | |
287 | $ hg ci -m 'delete target so it may be censored' |
|
283 | $ hg ci -m 'delete target so it may be censored' | |
288 | $ H2=`hg id --debug -i` |
|
284 | $ H2=`hg id --debug -i` | |
289 | $ hg censor -r $C4 target |
|
285 | $ hg --config extensions.censor= censor -r $C4 target | |
290 | $ hg cat -r $C4 target | head -n 10 |
|
286 | $ hg cat -r $C4 target | head -n 10 | |
291 | $ hg cat -r "$H2^^" target | head -n 10 |
|
287 | $ hg cat -r "$H2^^" target | head -n 10 | |
292 | Tainted file now super sanitized |
|
288 | Tainted file now super sanitized | |
@@ -314,7 +310,7 b' Can censor after revlog has expanded to ' | |||||
314 | $ hg revert -r "$H2^" target |
|
310 | $ hg revert -r "$H2^" target | |
315 | $ hg ci -m 'cleaned 100k passwords' |
|
311 | $ hg ci -m 'cleaned 100k passwords' | |
316 | $ H2=`hg id --debug -i` |
|
312 | $ H2=`hg id --debug -i` | |
317 | $ hg censor -r $C5 target |
|
313 | $ hg --config extensions.censor= censor -r $C5 target | |
318 | $ hg cat -r $C5 target | head -n 10 |
|
314 | $ hg cat -r $C5 target | head -n 10 | |
319 | $ hg cat -r $H2 target | head -n 10 |
|
315 | $ hg cat -r $H2 target | head -n 10 | |
320 | fresh start |
|
316 | fresh start | |
@@ -393,7 +389,7 b' Censored nodes can be pushed if they cen' | |||||
393 | $ CLEANREV=$H2 |
|
389 | $ CLEANREV=$H2 | |
394 | $ hg cat -r $REV target | head -n 10 |
|
390 | $ hg cat -r $REV target | head -n 10 | |
395 | Passwords: hunter2hunter2 |
|
391 | Passwords: hunter2hunter2 | |
396 | $ hg censor -r $REV target |
|
392 | $ hg --config extensions.censor= censor -r $REV target | |
397 | $ hg cat -r $REV target | head -n 10 |
|
393 | $ hg cat -r $REV target | head -n 10 | |
398 | $ hg cat -r $CLEANREV target | head -n 10 |
|
394 | $ hg cat -r $CLEANREV target | head -n 10 | |
399 | Re-sanitized; nothing to see here |
|
395 | Re-sanitized; nothing to see here | |
@@ -503,7 +499,7 b' Censored nodes can be imported on top of' | |||||
503 | Can import bundle where first revision of a file is censored |
|
499 | Can import bundle where first revision of a file is censored | |
504 |
|
500 | |||
505 | $ hg init ../rinit |
|
501 | $ hg init ../rinit | |
506 | $ hg censor -r 0 target |
|
502 | $ hg --config extensions.censor= censor -r 0 target | |
507 | $ hg bundle -r 0 --base null ../rinit/initbundle |
|
503 | $ hg bundle -r 0 --base null ../rinit/initbundle | |
508 | 1 changesets found |
|
504 | 1 changesets found | |
509 | $ cd ../rinit |
|
505 | $ cd ../rinit | |
@@ -553,7 +549,7 b' Censor the file' | |||||
553 |
|
549 | |||
554 | $ hg cat -r $B1 target | wc -l |
|
550 | $ hg cat -r $B1 target | wc -l | |
555 | *50002 (re) |
|
551 | *50002 (re) | |
556 | $ hg censor -r $B1 target |
|
552 | $ hg --config extensions.censor= censor -r $B1 target | |
557 | $ hg cat -r $B1 target | wc -l |
|
553 | $ hg cat -r $B1 target | wc -l | |
558 | *0 (re) |
|
554 | *0 (re) | |
559 |
|
555 |
General Comments 0
You need to be logged in to leave comments.
Login now