Fix stack overflow when trying to minify media files.

master
Icedream 2015-04-19 00:21:10 +02:00
parent dcdebcced4
commit 456cb2d593
4 changed files with 126 additions and 5 deletions

View File

@ -1,8 +1,5 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using TagLib;
using File = System.IO.File;
@ -26,6 +23,7 @@ namespace GarrysMod.AddonCreator.Addon
/// Creates a new <see cref="MinifiedMediaAddonFileInfo"/> instance using the given addon file.
/// </summary>
/// <param name="file">The addon file, supposedly a media file</param>
/// <param name="extension">The extension of this media file</param>
public MinifiedMediaAddonFileInfo(AddonFileInfo file, string extension)
{
_tempFile = Path.GetTempFileName();
@ -37,6 +35,8 @@ namespace GarrysMod.AddonCreator.Addon
var newTempFile = Path.Combine(
dirName,
Path.GetFileNameWithoutExtension(_tempFile) + "." + extension);
if (File.Exists(newTempFile))
File.Delete(newTempFile);
File.Move(_tempFile, newTempFile);
_tempFile = newTempFile;
@ -74,8 +74,7 @@ namespace GarrysMod.AddonCreator.Addon
}
}
using (var s = new FileStream(_tempFile, FileMode.Open, FileAccess.Read))
using (var tags = TagLib.File.Create(new StreamFileAbstraction(_tempFile, s, s)))
using (var tags = TagLib.File.Create(new FileAbstraction(_tempFile)))
{
if (tags.PossiblyCorrupt && !IgnoreCorrupted)
{

View File

@ -0,0 +1,44 @@
using System.IO;
using File = TagLib.File;
namespace GarrysMod.AddonCreator
{
class FileAbstraction : File.IFileAbstraction
{
private readonly string path;
private readonly MemoryStream realWriteStream;
public FileAbstraction(string path)
{
this.path = path;
realWriteStream = new MemoryStream();
WriteStream = new NonClosingStream(realWriteStream);
ReadStream = new FileStream(path, FileMode.Open, FileAccess.Read);
ReadStream.CopyTo(realWriteStream);
ReadStream.Position = realWriteStream.Position = 0;
Name = Path.GetFileName(path);
}
public string Name { get; private set; }
public Stream ReadStream { get; private set; }
public Stream WriteStream { get; private set; }
public void CloseStream(Stream stream)
{
ReadStream.Dispose();
if (!((NonClosingStream) WriteStream).Written)
return;
realWriteStream.Position = 0;
using (var s = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
{
realWriteStream.CopyTo(s);
}
realWriteStream.Dispose();
}
}
}

View File

@ -69,8 +69,10 @@
<Compile Include="Addon\MinifiedMediaAddonFileInfo.cs" />
<Compile Include="Extensions.cs" />
<Compile Include="Addon\JsonAddonFileInfo.cs" />
<Compile Include="FileAbstraction.cs" />
<Compile Include="Hashing\Crc32.cs" />
<Compile Include="Addon\PhysicalAddonFileInfo.cs" />
<Compile Include="NonClosingStream.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Addon\SegmentedAddonFileInfo.cs" />

View File

@ -0,0 +1,76 @@
using System.IO;
namespace GarrysMod.AddonCreator
{
class NonClosingStream : Stream
{
private readonly Stream _stream;
public NonClosingStream(Stream stream)
{
_stream = stream;
}
public override bool CanRead
{
get { return _stream.CanRead; }
}
public override bool CanSeek
{
get { return _stream.CanSeek; }
}
public override bool CanWrite
{
get { return _stream.CanWrite; }
}
public override long Length
{
get { return _stream.Length; }
}
public override long Position
{
get { return _stream.Position; }
set { _stream.Position = value; }
}
public override void Flush()
{
_stream.Flush();
}
public override void Close()
{
}
protected override void Dispose(bool disposing)
{
}
public override long Seek(long offset, SeekOrigin origin)
{
return _stream.Seek(offset, origin);
}
public override void SetLength(long value)
{
_stream.SetLength(value);
}
public override int Read(byte[] buffer, int offset, int count)
{
return _stream.Read(buffer, offset, count);
}
public override void Write(byte[] buffer, int offset, int count)
{
_stream.Write(buffer, offset, count);
Written = true;
}
public bool Written { get; private set; }
}
}