Browse Source

Add CodestreamMarker, don't manually check for out-of-bounds

Bit Reader should automatically throw if it reads out of bounds anyway
pull/3153/head
winscripter 1 week ago
parent
commit
7e236700ad
  1. 36
      src/ImageSharp/Formats/Jxl/Processing/Decoder/JxlDecoderCore.cs
  2. 7
      src/ImageSharp/Formats/Jxl/Processing/JxlShared.cs

36
src/ImageSharp/Formats/Jxl/Processing/Decoder/JxlDecoderCore.cs

@ -223,7 +223,7 @@ internal sealed class JxlDecoderCore : ImageDecoderCore, IDisposable
/// <summary> /// <summary>
/// Output data for extra channels. /// Output data for extra channels.
/// </summary> /// </summary>
private List<JxlExtraChannelOutput> extraChannelOutputs = []; private readonly List<JxlExtraChannelOutput> extraChannelOutputs = [];
/// <summary> /// <summary>
/// Codec metadata if present. /// Codec metadata if present.
@ -255,7 +255,7 @@ internal sealed class JxlDecoderCore : ImageDecoderCore, IDisposable
/// </summary> /// </summary>
private long nextSection; private long nextSection;
private List<byte> sectionProcessed = []; private readonly List<byte> sectionProcessed = [];
/// <summary> /// <summary>
/// The frame header, if present. /// The frame header, if present.
@ -301,11 +301,11 @@ internal sealed class JxlDecoderCore : ImageDecoderCore, IDisposable
/// <summary> /// <summary>
/// All frame reference.s /// All frame reference.s
/// </summary> /// </summary>
private List<JxlFrameReference> frameReferences = []; private readonly List<JxlFrameReference> frameReferences = [];
private List<int> frameExternalToInternal = []; private readonly List<int> frameExternalToInternal = [];
private List<byte> frameRequired = []; private readonly List<byte> frameRequired = [];
/// <summary> /// <summary>
/// Codestream input data is temporarily copied here. /// Codestream input data is temporarily copied here.
@ -802,7 +802,7 @@ internal sealed class JxlDecoderCore : ImageDecoderCore, IDisposable
throw new EndOfStreamException(); throw new EndOfStreamException();
} }
if (secondByte == CodestreamMarker) if (secondByte == JxlShared.CodestreamMarker)
{ {
return JxlSignature.CodeStream; return JxlSignature.CodeStream;
} }
@ -961,7 +961,7 @@ internal sealed class JxlDecoderCore : ImageDecoderCore, IDisposable
{ {
const long bufferLimit = 1 << 48; const long bufferLimit = 1 << 48;
return length < bufferLimit && return length < bufferLimit &&
(length + this.jxlpOooBufferTotal + (this.codestreamCopy?.Memory.Length ?? 0)) < bufferLimit; (length + this.jxlpOooBufferTotal + (this.codestreamCopy?.AsMemory().Length ?? 0)) < bufferLimit;
} }
public bool TryInjectNextBufferedJxlpBox() public bool TryInjectNextBufferedJxlpBox()
@ -1471,14 +1471,14 @@ internal sealed class JxlDecoderCore : ImageDecoderCore, IDisposable
/// Reads a single bundle into <paramref name="bundle"/>. /// Reads a single bundle into <paramref name="bundle"/>.
/// </summary> /// </summary>
/// <typeparam name="T">Type of the bundle to read.</typeparam> /// <typeparam name="T">Type of the bundle to read.</typeparam>
/// <param name="data">Bundle binary data.</param> /// <param name="stream">Stream to read data from.</param>
/// <param name="br">Bit reader to continue from.</param> /// <param name="br">Bit reader to continue from.</param>
/// <param name="bundle">The bundle to parse.</param> /// <param name="bundle">The bundle to parse.</param>
/// <returns>Status of parsing the bundle.</returns> /// <returns>Status of parsing the bundle.</returns>
private bool ReadBundle<T>(Span<byte> data, JxlBitReader br, T bundle) private bool ReadBundle<T>(Stream stream, JxlBitReader br, T bundle)
where T : IJxlFields where T : IJxlFields
{ {
JxlBitReader reader = new(data); JxlBitReader reader = new(stream);
reader.SkipBits64((ulong)br.TotalBitsConsumed); reader.SkipBits64((ulong)br.TotalBitsConsumed);
bool canRead = JxlBundle.CanRead(reader, bundle); bool canRead = JxlBundle.CanRead(reader, bundle);
@ -1646,22 +1646,6 @@ internal sealed class JxlDecoderCore : ImageDecoderCore, IDisposable
this.frameDecoder.ProcessSections(sectionInfo, sectionStatus); this.frameDecoder.ProcessSections(sectionInfo, sectionStatus);
bool outOfBounds = false;
foreach (JxlSectionInfo info in sectionInfo)
{
if (!info.BitReader.AllReadsWithinBounds)
{
outOfBounds = true;
break;
}
}
if (outOfBounds)
{
throw new InvalidOperationException("Frame out of bounds");
}
for (int i = 0; i < sectionStatus.Count; i++) for (int i = 0; i < sectionStatus.Count; i++)
{ {
JxlSectionStatus ss = sectionStatus[i]; JxlSectionStatus ss = sectionStatus[i];

7
src/ImageSharp/Formats/Jxl/Processing/JxlShared.cs

@ -18,6 +18,13 @@ internal static class JxlShared
/// </summary> /// </summary>
public const int MaximumNumberOfReferenceFrames = 4; public const int MaximumNumberOfReferenceFrames = 4;
/// <summary>
/// Reserved by ISO/IEC 10918-1. LF causes files opened in text mode
/// to be rejected because the marker changes to 0x0D instead. The
/// 0xFF prefix also ensures there were no 7-bit transmission limitations.
/// </summary>
public const byte CodestreamMarker = 0x0A;
/// <summary> /// <summary>
/// Gets the 12-byte signature (a.k.a. magic) for JPEG XL files. /// Gets the 12-byte signature (a.k.a. magic) for JPEG XL files.
/// </summary> /// </summary>

Loading…
Cancel
Save