Skip to content

Commit 3eceb02

Browse files
author
David Pierson
committed
Z-1650 Fixed updating ODT archives in memory. Exposed exceptions in updating in ZipFile.
1 parent ae622a8 commit 3eceb02

1 file changed

Lines changed: 47 additions & 33 deletions

File tree

src/Zip/ZipFile.cs

Lines changed: 47 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@
3838
// exception statement from your version.
3939

4040
// HISTORY
41-
// 22-12-2009 DavidPierson Added AES support
41+
// 2009-12-22 Z-1649 Added AES support
42+
// 2010-03-02 Z-1650 Fixed updating ODT archives in memory. Exposed exceptions in updating.
4243

4344
using System;
4445
using System.Collections;
@@ -1423,6 +1424,18 @@ public void BeginUpdate(IArchiveStorage archiveStorage, IDynamicDataSource dataS
14231424
updateIndex_.Add(entry.Name, index);
14241425
}
14251426

1427+
// We must sort by offset before using offset's calculated sizes
1428+
updates_.Sort(new UpdateComparer());
1429+
1430+
int idx = 0;
1431+
foreach (ZipUpdate update in updates_) {
1432+
//If last entry, there is no next entry offset to use
1433+
if (idx == updates_.Count - 1)
1434+
break;
1435+
1436+
update.OffsetBasedSize = ((ZipUpdate)updates_[idx + 1]).Entry.Offset - update.Entry.Offset;
1437+
idx++;
1438+
}
14261439
updateCount_ = updates_.Count;
14271440

14281441
contentsEdited_ = false;
@@ -2502,10 +2515,16 @@ void CopyEntryDirect(ZipFile workFile, ZipUpdate update, ref long destinationPos
25022515

25032516
sourcePosition = baseStream_.Position + nameLength + extraLength;
25042517

2505-
if ( skipOver ) {
2506-
destinationPosition +=
2507-
(sourcePosition - entryDataOffset) + NameLengthOffset + // Header size
2508-
update.Entry.CompressedSize + GetDescriptorSize(update);
2518+
if (skipOver) {
2519+
if (update.OffsetBasedSize != -1)
2520+
destinationPosition += update.OffsetBasedSize;
2521+
else
2522+
// TODO: Find out why this calculation comes up 4 bytes short on some entries in ODT (Office Document Text) archives.
2523+
// WinZip produces a warning on these entries:
2524+
// "caution: value of lrec.csize (compressed size) changed from ..."
2525+
destinationPosition +=
2526+
(sourcePosition - entryDataOffset) + NameLengthOffset + // Header size
2527+
update.Entry.CompressedSize + GetDescriptorSize(update);
25092528
}
25102529
else {
25112530
if ( update.Entry.CompressedSize > 0 ) {
@@ -2674,7 +2693,6 @@ void RunUpdates()
26742693
{
26752694
long sizeEntries = 0;
26762695
long endOfStream = 0;
2677-
bool allOk = true;
26782696
bool directUpdate = false;
26792697
long destinationPosition = 0; // NOT SFX friendly
26802698

@@ -2780,38 +2798,23 @@ void RunUpdates()
27802798
}
27812799
}
27822800
}
2783-
catch(Exception) {
2784-
// TODO Catching exceptions here is rumoured to allow invalid archives to be created with no warning?
2785-
allOk = false;
2786-
}
2787-
finally {
2788-
if ( directUpdate ) {
2789-
if ( allOk ) {
2790-
workFile.baseStream_.Flush();
2791-
workFile.baseStream_.SetLength(endOfStream);
2792-
}
2793-
}
2794-
else {
2795-
workFile.Close();
2801+
catch {
2802+
workFile.Close();
2803+
if (!directUpdate && (workFile.Name != null)) {
2804+
File.Delete(workFile.Name);
27962805
}
2806+
throw;
27972807
}
27982808

2799-
if ( allOk ) {
2800-
if ( directUpdate ) {
2801-
isNewArchive_ = false;
2802-
workFile.baseStream_.Flush();
2803-
ReadEntries();
2804-
}
2805-
else {
2806-
baseStream_.Close();
2807-
Reopen(archiveStorage_.ConvertTemporaryToFinal());
2808-
}
2809+
if (directUpdate) {
2810+
workFile.baseStream_.SetLength(endOfStream);
2811+
workFile.baseStream_.Flush();
2812+
isNewArchive_ = false;
2813+
ReadEntries();
28092814
}
28102815
else {
2811-
workFile.Close();
2812-
if ( !directUpdate && (workFile.Name != null) ) {
2813-
File.Delete(workFile.Name);
2814-
}
2816+
baseStream_.Close();
2817+
Reopen(archiveStorage_.ConvertTemporaryToFinal());
28152818
}
28162819
}
28172820

@@ -2955,6 +2958,16 @@ public long CrcPatchOffset
29552958
set { crcPatchOffset_ = value; }
29562959
}
29572960

2961+
/// <summary>
2962+
/// Get/set the size calculated by offset.
2963+
/// Specifically, the difference between this and next entry's starting offset.
2964+
/// </summary>
2965+
public long OffsetBasedSize
2966+
{
2967+
get { return _offsetBasedSize; }
2968+
set { _offsetBasedSize = value; }
2969+
}
2970+
29582971
public Stream GetSource()
29592972
{
29602973
Stream result = null;
@@ -2973,6 +2986,7 @@ public Stream GetSource()
29732986
string filename_;
29742987
long sizePatchOffset_ = -1;
29752988
long crcPatchOffset_ = -1;
2989+
long _offsetBasedSize = -1;
29762990
#endregion
29772991
}
29782992

0 commit comments

Comments
 (0)