fix: Wrong keyword encoding, bad buffer, update cache fix

Was using ASCII for keyword and was generating inconsistent CRC whoops
This commit is contained in:
Teacup
2025-08-08 17:57:55 -07:00
committed by Natsumi
parent 06e06a7164
commit 7fe8f4e079
4 changed files with 23 additions and 17 deletions

View File

@@ -7,7 +7,7 @@ using System.Text;
namespace VRCX;
public struct PNGChunk
public class PNGChunk
{
public int Index;
public int Length;
@@ -58,7 +58,7 @@ public struct PNGChunk
*/
// Parse keyword as null-terminated string
var keywordEncoding = Encoding.GetEncoding("ISO-8859-1");
var keywordEncoding = Encoding.UTF8;
int keywordLength = 0;
for (int i = 0; i < chunkLength; i++)
{
@@ -126,8 +126,9 @@ public struct PNGChunk
public bool ExistsInFile(FileStream fileStream)
{
fileStream.Seek(Index, SeekOrigin.Begin);
byte[] buffer = new byte[Length];
fileStream.ReadExactly(buffer, 0, Length);
byte[] buffer = new byte[4];
fileStream.ReadExactly(buffer, 0, 4);
if (BitConverter.IsLittleEndian)
Array.Reverse(buffer, 0, 4);
@@ -137,14 +138,15 @@ public struct PNGChunk
return false;
fileStream.Seek(4 + chunkLength, SeekOrigin.Current);
fileStream.ReadExactly(buffer, 0, Length);
fileStream.ReadExactly(buffer, 0, 4);
if (BitConverter.IsLittleEndian)
Array.Reverse(buffer, 0, 4);
uint crc = BitConverter.ToUInt32(buffer, 0);
uint calculatedCRC = CalculateCRC();
return crc == CalculateCRC();
return crc == calculatedCRC;
}
/// <summary>
@@ -186,7 +188,7 @@ public struct PNGChunk
public uint CalculateCRC()
{
var chunkTypeBytes = Encoding.ASCII.GetBytes(ChunkType);
var chunkTypeBytes = Encoding.UTF8.GetBytes(ChunkType);
return Crc32(Data, 0, Data.Length, Crc32(chunkTypeBytes, 0, chunkTypeBytes.Length, 0));
}

View File

@@ -60,7 +60,7 @@ public class PNGFile : IDisposable
public PNGChunk? GetChunkReverse(PNGChunkTypeFilter chunkTypeFilter)
{
var chunk = ReadChunkReverse(chunkTypeFilter);
if (chunk.HasValue &&chunk.Value.IsZero())
if (chunk != null && chunk.IsZero())
return null;
return chunk;
@@ -147,10 +147,10 @@ public class PNGFile : IDisposable
}
fileStream.SetLength(fileStream.Length - deleteLength);
metadataChunkCache.Remove(chunk);
// update the index of all cached chunks
// Update the index of cached chunks
for (int i = 0; i < metadataChunkCache.Count; i++)
{
var cachedChunk = metadataChunkCache[i];

View File

@@ -16,9 +16,9 @@ namespace VRCX
public static string ReadResolution(PNGFile pngFile)
{
var ihdrChunk = pngFile.GetChunk(PNGChunkTypeFilter.IHDR);
if (ihdrChunk.HasValue)
if (ihdrChunk != null)
{
var resolution = ihdrChunk.Value.ReadIHDRChunkResolution();
var resolution = ihdrChunk.ReadIHDRChunkResolution();
return resolution.Item1 + "x" + resolution.Item2;
}
@@ -42,9 +42,9 @@ namespace VRCX
if (legacySearch)
{
var legacyTextChunk = pngFile.GetChunkReverse(PNGChunkTypeFilter.iTXt);
if (legacyTextChunk.HasValue)
if (legacyTextChunk != null)
{
var data = legacyTextChunk.Value.ReadITXtChunk();
var data = legacyTextChunk.ReadITXtChunk();
if (data.Item1 == keyword)
return data.Item2;
}
@@ -91,7 +91,7 @@ namespace VRCX
public static PNGChunk GenerateTextChunk(string keyword, string text)
{
byte[] textBytes = Encoding.UTF8.GetBytes(text);
byte[] keywordBytes = Encoding.GetEncoding("ISO-8859-1").GetBytes(keyword);
byte[] keywordBytes = Encoding.UTF8.GetBytes(keyword);
List<byte> constructedTextChunk = new List<byte>();
constructedTextChunk.AddRange(keywordBytes);

View File

@@ -209,7 +209,7 @@ namespace VRCX
// Check for chunk only present in files created by older modded versions of vrchat. (LFS, screenshotmanager), which put their metadata at the end of the file (which is not in spec bro).
// Searching from the end of the file is a slower bruteforce operation so only do it if we have to.
if (result.Count == 0 && pngFile.GetChunk(PNGChunkTypeFilter.sRGB).HasValue)
if (result.Count == 0 && pngFile.GetChunk(PNGChunkTypeFilter.sRGB) != null)
{
var lfsMetadata = PNGHelper.ReadTextChunk("Description", pngFile, true);
@@ -233,7 +233,11 @@ namespace VRCX
{
using var pngFile = new PNGFile(path);
var chunk = PNGHelper.GenerateTextChunk("Description", text);
return pngFile.WriteChunk(chunk);
pngFile.WriteChunk(chunk);
DeleteTextMetadata(path, true);
return true;
}
public static ScreenshotMetadata ParseVRCImage(string xmlString)