mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-07-08 13:14:30 -05:00
Merge pull request #1471 from ousttrue/fix/glb_parse_check
glb parse の throw を更新
This commit is contained in:
commit
3e8a2e7ee0
|
|
@ -24,30 +24,6 @@ namespace UniGLTF
|
|||
s.Write(GLB_VERSION, 0, GLB_VERSION.Length);
|
||||
}
|
||||
|
||||
public static int TryParse(ArraySegment<Byte> bytes, out int pos, out Exception message)
|
||||
{
|
||||
pos = 0;
|
||||
|
||||
if (!bytes.Slice(0, 4).SequenceEqual(GLB_MAGIC))
|
||||
{
|
||||
message = new FormatException("invalid magic");
|
||||
return 0;
|
||||
}
|
||||
pos += 4;
|
||||
|
||||
if (!bytes.Slice(pos, 4).SequenceEqual(GLB_VERSION))
|
||||
{
|
||||
message = new FormatException("invalid magic");
|
||||
return 0;
|
||||
}
|
||||
pos += 4;
|
||||
|
||||
var totalLength = BitConverter.ToInt32(bytes.Array, bytes.Offset + pos);
|
||||
pos += 4;
|
||||
|
||||
message = null;
|
||||
return totalLength;
|
||||
}
|
||||
}
|
||||
|
||||
public struct GlbChunk
|
||||
|
|
@ -219,75 +195,5 @@ namespace UniGLTF
|
|||
throw new FormatException("unknown chunk type: " + src);
|
||||
}
|
||||
}
|
||||
|
||||
public static Glb Parse(Byte[] bytes)
|
||||
{
|
||||
return Parse(new ArraySegment<byte>(bytes));
|
||||
}
|
||||
|
||||
public static Glb Parse(ArraySegment<Byte> bytes)
|
||||
{
|
||||
if (TryParse(bytes, out Glb glb, out Exception ex))
|
||||
{
|
||||
return glb;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool TryParse(Byte[] bytes, out Glb glb, out Exception ex)
|
||||
{
|
||||
return TryParse(new ArraySegment<byte>(bytes), out glb, out ex);
|
||||
}
|
||||
|
||||
public static bool TryParse(ArraySegment<Byte> bytes, out Glb glb, out Exception ex)
|
||||
{
|
||||
glb = default(Glb);
|
||||
if (bytes.Count == 0)
|
||||
{
|
||||
ex = new Exception("empty bytes");
|
||||
return false;
|
||||
}
|
||||
|
||||
var length = GlbHeader.TryParse(bytes, out int pos, out ex);
|
||||
if (length == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bytes = bytes.Slice(0, length);
|
||||
|
||||
try
|
||||
{
|
||||
var chunks = new List<GlbChunk>();
|
||||
while (pos < bytes.Count)
|
||||
{
|
||||
var chunkDataSize = BitConverter.ToInt32(bytes.Array, bytes.Offset + pos);
|
||||
pos += 4;
|
||||
|
||||
//var type = (GlbChunkType)BitConverter.ToUInt32(bytes, pos);
|
||||
var chunkTypeBytes = bytes.Slice(pos, 4).Where(x => x != 0).ToArray();
|
||||
var chunkTypeStr = Encoding.ASCII.GetString(chunkTypeBytes);
|
||||
pos += 4;
|
||||
|
||||
chunks.Add(new GlbChunk
|
||||
{
|
||||
ChunkTypeString = chunkTypeStr,
|
||||
Bytes = bytes.Slice(pos, chunkDataSize)
|
||||
});
|
||||
|
||||
pos += chunkDataSize;
|
||||
}
|
||||
|
||||
glb = new Glb(chunks[0], chunks[1]);
|
||||
return true;
|
||||
}
|
||||
catch (Exception _ex)
|
||||
{
|
||||
ex = _ex;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace UniGLTF
|
||||
|
|
@ -14,7 +13,7 @@ namespace UniGLTF
|
|||
|
||||
public static GlbChunkType ToChunkType(this string src)
|
||||
{
|
||||
switch(src)
|
||||
switch (src)
|
||||
{
|
||||
case "BIN":
|
||||
return GlbChunkType.BIN;
|
||||
|
|
@ -48,27 +47,33 @@ namespace UniGLTF
|
|||
|
||||
public static List<GlbChunk> ParseGlbChunks(Byte[] bytes)
|
||||
{
|
||||
if (bytes.Length == 0)
|
||||
//
|
||||
// glb header(12byte)
|
||||
//
|
||||
if (bytes.Length < 12)
|
||||
{
|
||||
throw new Exception("empty bytes");
|
||||
throw new GlbParseException("glb header not found");
|
||||
}
|
||||
|
||||
int pos = 0;
|
||||
if (Encoding.ASCII.GetString(bytes, 0, 4) != GLB_MAGIC)
|
||||
{
|
||||
throw new Exception("invalid magic");
|
||||
throw new GlbParseException("invalid magic");
|
||||
}
|
||||
pos += 4;
|
||||
|
||||
var version = BitConverter.ToUInt32(bytes, pos);
|
||||
if (version != GLB_VERSION)
|
||||
{
|
||||
Debug.LogWarningFormat("unknown version: {0}", version);
|
||||
return null;
|
||||
throw new GlbParseException($"unknown version: {version}");
|
||||
}
|
||||
pos += 4;
|
||||
|
||||
//var totalLength = BitConverter.ToUInt32(bytes, pos);
|
||||
var totalLength = BitConverter.ToUInt32(bytes, pos);
|
||||
if (bytes.Length < totalLength)
|
||||
{
|
||||
throw new GlbParseException($"not enough size: {bytes.Length} < {totalLength}");
|
||||
}
|
||||
pos += 4;
|
||||
|
||||
var chunks = new List<GlbChunk>();
|
||||
|
|
|
|||
|
|
@ -14,4 +14,12 @@ namespace UniGLTF
|
|||
public UniGLTFNotSupportedException(string fmt, params object[] args) : this(string.Format(fmt, args)) { }
|
||||
public UniGLTFNotSupportedException(string msg) : base(msg) { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Exception in parse the glb header
|
||||
/// </summary>
|
||||
public class GlbParseException : UniGLTFException
|
||||
{
|
||||
public GlbParseException(string msg) : base(msg) { }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace UniGLTF
|
||||
|
|
@ -37,5 +39,38 @@ namespace UniGLTF
|
|||
// NOTE: 大文字小文字が違うだけの名前は、同一としてみなされ、Suffix が付く。
|
||||
Assert.AreEqual("foobar__UNIGLTF__DUPLICATED__2", parsed.GLTF.textures[1].name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ヘッダが正しいが、後ろが切れている場合に throw する
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void GlbLengthTest()
|
||||
{
|
||||
var env = System.Environment.GetEnvironmentVariable("GLTF_SAMPLE_MODELS");
|
||||
if (string.IsNullOrEmpty(env))
|
||||
{
|
||||
return;
|
||||
}
|
||||
var root = new DirectoryInfo($"{env}/2.0");
|
||||
if (!root.Exists)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var path = Path.Combine(root.ToString(), "DamagedHelmet\\glTF-Binary\\DamagedHelmet.glb");
|
||||
Assert.True(File.Exists(path));
|
||||
|
||||
var bytes = File.ReadAllBytes(path);
|
||||
var data = new GlbBinaryParser(bytes, Path.GetFileNameWithoutExtension(path)).Parse();
|
||||
|
||||
// glb header + 1st chunk only
|
||||
var mod = bytes.Take(12 + 8 + data.Chunks[0].Bytes.Count).ToArray();
|
||||
|
||||
Assert.Throws<GlbParseException>(() =>
|
||||
{
|
||||
// 再パース
|
||||
var data2 = new GlbBinaryParser(mod, Path.GetFileNameWithoutExtension(path)).Parse();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ namespace UniVRM10
|
|||
|
||||
static JsonNode GetVRM0(byte[] bytes)
|
||||
{
|
||||
var glb = UniGLTF.Glb.Parse(bytes);
|
||||
var json = glb.Json.Bytes.ParseAsJson();
|
||||
var glb = new GlbBinaryParser(bytes, "vrm0").Parse();
|
||||
var json = glb.Json.ParseAsJson();
|
||||
return json["extensions"]["VRM"];
|
||||
}
|
||||
|
||||
|
|
@ -50,8 +50,8 @@ namespace UniVRM10
|
|||
var vrm0Json = GetVRM0(vrm0Bytes);
|
||||
|
||||
var vrm1 = MigrationVrm.Migrate(vrm0Bytes);
|
||||
var glb = UniGLTF.Glb.Parse(vrm1);
|
||||
var json = glb.Json.Bytes.ParseAsJson();
|
||||
var glb = new GlbBinaryParser(vrm1, "vrm1").Parse();
|
||||
var json = glb.Json.ParseAsJson();
|
||||
var gltf = UniGLTF.GltfDeserializer.Deserialize(json);
|
||||
|
||||
MigrationVrm.Check(vrm0Json, GetExtension(gltf.extensions, UniGLTF.Extensions.VRMC_vrm.GltfDeserializer.ExtensionNameUtf8,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user