Allow CreateRelationship to work with FileAccess.Write (dotnet/corefx#35763)
authorEric StJohn <ericstj@microsoft.com>
Tue, 5 Mar 2019 16:48:42 +0000 (08:48 -0800)
committerGitHub <noreply@github.com>
Tue, 5 Mar 2019 16:48:42 +0000 (08:48 -0800)
commit948faa1baf19119f5987bcf7be8deb5ecddd4c94
tree66bfa42d1b2477b59ee4f109c9f1e01ab0f3cb14
parent039c68d024b94f88b05c4700bc101d7605effa29
Allow CreateRelationship to work with FileAccess.Write (dotnet/corefx#35763)

When adding a relationship InternalRelationshipCollection was creating a part
but not writing anything to it.  This caused an empty entry to be created in
the zip archive which later needed to be rewritten.  That's disallowed with
FileAccess.Write.  Instead, avoid creating the entry until it's content is
written.

When writing a relationship file InternalRelationshipCollection was attempting
to truncate any existing content.  This throws when the package is open  with
FileAccess.Write since the part stream is not seekable.  Don't do the seek
when package is open for FileAccess.Write since no pre-existing content is
possible.

In Package.PartExists don't attempt to get the part.  PartExists on .NETCore
only needs to query its local list of parts.  Since it isn't returning a
mutable part, it doesn't need to throw for packages opened with FileAccess.Write.

Avoid out of bounds exception when enumerating part keys. The fix that delays
creating the relationship part until its content exposed an issue in
DoOperationOnEachPart.  This was creating a copy of the part keys, but then
enumerating over the length of original list instead of the copy.  Since I
delayed the creating of a part until it was flushed this made the length change
while iterating the loop.  Since this code was using its copied list of keys
it should have never been using the original bounds.

Commit migrated from https://github.com/dotnet/corefx/commit/1822fec76a7bc02764ffa94c0e1f97b8ebfdbdea
src/libraries/System.IO.Packaging/src/System/IO/Packaging/InternalRelationshipCollection.cs
src/libraries/System.IO.Packaging/src/System/IO/Packaging/Package.cs
src/libraries/System.IO.Packaging/tests/Tests.cs