Skip to content

System.IO.Packaging part stream has a memory leak when writing a large stream #23750

@twsouthwick

Description

@twsouthwick

This was found through the DocumentFormat.OpenXML library which uses System.IO.Packaging extensively (original issue: dotnet/Open-XML-SDK#244). The issue logged there is trying to generate a large Excel document which uses a working set of around 10mb on .NET 4.7, while it grows quite quickly until hitting a OutOfMemoryException. I've simplified the issue to remove the dependency on DocumentFormat.OpenXML and it appears to be isolated to writing to a Part within a Package.

Source

using System;
using System.IO;
using System.IO.Packaging;

namespace MemoryRepro
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var fs = new FileStream(Path.GetTempFileName(), FileMode.Create, FileAccess.ReadWrite))
            using (var package = Package.Open(fs, FileMode.Create))
            {
                var part = package.CreatePart(new Uri("/part", UriKind.Relative), "something/sometype");

                using (var stream = part.GetStream())
                using (var writer = new StreamWriter(stream))
                {
                    for (var i = 0; i < int.MaxValue; i++)
                    {
                        writer.Write("hello");
                    }
                }
            }
        }
    }
}

Project

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net47</TargetFramework>
    <!--<TargetFramework>netcoreapp2.0</TargetFramework>-->
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="System.IO.Packaging" Version="4.4.0" />
  </ItemGroup>

</Project>

This repro code appears to have a working set of around 60mb running on .NET 4.7, while it grows very quickly on .NET Core 2.0

The error on .NET Core 2.0 is:

Unhandled Exception: System.IO.IOException: Stream was too long.
   at System.IO.MemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count)
   at System.IO.Compression.WrappedStream.Write(Byte[] buffer, Int32 offset, Int32 count)
   at System.IO.StreamWriter.Flush(Boolean flushStream, Boolean flushEncoder)
   at System.IO.StreamWriter.Write(String value)
   at MemoryRepro.Program.Main(String[] args) in c:\users\tasou\source\repos\MemoryRepro\MemoryRepro\Program.cs:line 21

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions