Mercurial > hg4j
comparison src/org/tmatesoft/hg/repo/HgDataFile.java @ 323:4c7e3ba67213
Exception when analyzing metadata of an empty renamed file
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Fri, 30 Sep 2011 08:44:48 +0200 |
parents | d68dcb3b5f49 |
children | a674b8590362 |
comparison
equal
deleted
inserted
replaced
322:d68dcb3b5f49 | 323:4c7e3ba67213 |
---|---|
219 try { | 219 try { |
220 insp.checkFailed(); // XXX is there real need to throw IOException from ContentPipe? | 220 insp.checkFailed(); // XXX is there real need to throw IOException from ContentPipe? |
221 } catch (HgDataStreamException ex) { | 221 } catch (HgDataStreamException ex) { |
222 throw ex; | 222 throw ex; |
223 } catch (IOException ex) { | 223 } catch (IOException ex) { |
224 throw new HgDataStreamException(getPath(), ex); | 224 throw new HgDataStreamException(getPath(), ex).setRevisionNumber(revision); |
225 } catch (HgException ex) { | 225 } catch (HgException ex) { |
226 // shall not happen, unless we changed ContentPipe or its subclass | 226 // shall not happen, unless we changed ContentPipe or its subclass |
227 throw new HgDataStreamException(getPath(), ex.getClass().getName(), ex); | 227 throw new HgDataStreamException(getPath(), ex.getClass().getName(), ex); |
228 } | 228 } |
229 } | 229 } |
437 throw new CancelledException(); | 437 throw new CancelledException(); |
438 } | 438 } |
439 }); | 439 }); |
440 } catch (CancelledException ex) { | 440 } catch (CancelledException ex) { |
441 // it's ok, we did that | 441 // it's ok, we did that |
442 } catch (Exception ex) { | |
443 throw new HgDataStreamException(getPath(), "Can't initialize metadata", ex).setRevisionNumber(localRev); | |
444 } | 442 } |
445 } | 443 } |
446 | 444 |
447 private static final class MetadataEntry { | 445 private static final class MetadataEntry { |
448 private final String entry; | 446 private final String entry; |
571 // which can't be used here because we can't convert bytes to chars as we read them | 569 // which can't be used here because we can't convert bytes to chars as we read them |
572 // (there might be multi-byte encoding), and we need to collect all bytes before converting to string | 570 // (there might be multi-byte encoding), and we need to collect all bytes before converting to string |
573 ByteArrayOutputStream bos = new ByteArrayOutputStream(); | 571 ByteArrayOutputStream bos = new ByteArrayOutputStream(); |
574 String key = null, value = null; | 572 String key = null, value = null; |
575 boolean byteOne = false; | 573 boolean byteOne = false; |
574 boolean metadataIsComplete = false; | |
576 for (int i = 2; i < daLength; i++) { | 575 for (int i = 2; i < daLength; i++) { |
577 byte b = data.readByte(); | 576 byte b = data.readByte(); |
578 if (b == '\n') { | 577 if (b == '\n') { |
579 if (byteOne) { // i.e. \n follows 1 | 578 if (byteOne) { // i.e. \n follows 1 |
580 lastEntryStart = i+1; | 579 lastEntryStart = i+1; |
580 metadataIsComplete = true; | |
581 // XXX is it possible to have here incomplete key/value (i.e. if last pair didn't end with \n) | 581 // XXX is it possible to have here incomplete key/value (i.e. if last pair didn't end with \n) |
582 // if yes, need to set metadataIsComplete to true in that case as well | |
582 break; | 583 break; |
583 } | 584 } |
584 if (key == null || lastColon == -1 || i <= lastColon) { | 585 if (key == null || lastColon == -1 || i <= lastColon) { |
585 throw new IllegalStateException(); // FIXME log instead and record null key in the metadata. Ex just to fail fast during dev | 586 throw new IllegalStateException(); // FIXME log instead and record null key in the metadata. Ex just to fail fast during dev |
586 } | 587 } |
608 byteOne = true; | 609 byteOne = true; |
609 } else { | 610 } else { |
610 bos.write(b); | 611 bos.write(b); |
611 } | 612 } |
612 } | 613 } |
613 if (data.isEmpty() || !byteOne) { | 614 // data.isEmpty is not reliable, renamed files of size==0 keep only metadata |
615 if (!metadataIsComplete) { | |
616 // XXX perhaps, worth a testcase (empty file, renamed, read or ask ifCopy | |
614 throw new HgDataStreamException(fname, "Metadata is not closed properly", null); | 617 throw new HgDataStreamException(fname, "Metadata is not closed properly", null); |
615 } | 618 } |
616 return lastEntryStart; | 619 return lastEntryStart; |
617 } | 620 } |
618 | 621 |