Merge pull request #445 from PoChang007/PreventInvalidFileName

check invalid file name
This commit is contained in:
ousttrue 2020-06-25 19:30:23 +09:00 committed by GitHub
commit a5aa74fe09
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 131 additions and 3 deletions

View File

@ -1,4 +1,5 @@
using System.IO;
using System.Text.RegularExpressions;
using UnityEngine;
namespace UniGLTF
@ -63,6 +64,8 @@ namespace UniGLTF
};
public static string EscapeFilePath(this string path)
{
path = Regex.Replace(path, @"[\u0000-\u001F\u007F]", "+");
foreach(var x in EscapeChars)
{
path = path.Replace(x, '+');

View File

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using UniGLTF;
using UnityEditor;
using UnityEngine;
@ -92,6 +93,11 @@ namespace VRM
public bool RemoveVertexColor = false;
#endregion
public static bool IsFileNameLengthTooLong(string fileName)
{
return fileName.Length > 64;
}
public struct Validation
{
/// <summary>
@ -190,7 +196,7 @@ namespace VRM
if (ReduceBlendshape && Source.GetComponent<VRMBlendShapeProxy>() == null)
{
yield return Validation.Error("ReduceBlendshapeSize is need VRMBlendShapeProxy, you need to convert to VRM once.");
yield return Validation.Error("ReduceBlendshapeSize needs VRMBlendShapeProxy. You need to convert to VRM once.");
}
var vertexColor = Source.GetComponentsInChildren<SkinnedMeshRenderer>().Any(x => x.sharedMesh.colors.Length > 0);
@ -228,6 +234,61 @@ namespace VRM
yield return Validation.Warning(string.Format("unknown material '{0}' is used. this will export as `Standard` fallback", material.shader.name));
}
foreach (var material in materials)
{
if (IsFileNameLengthTooLong(material.name))
yield return Validation.Error(string.Format("FileName '{0}' is too long. ", material.name));
}
var textureNameList = new List<string>();
foreach (var material in materials)
{
var shader = material.shader;
int propertyCount = ShaderUtil.GetPropertyCount(shader);
for (int i = 0; i < propertyCount; i++)
{
if (ShaderUtil.GetPropertyType(shader, i) == ShaderUtil.ShaderPropertyType.TexEnv)
{
if ((material.GetTexture(ShaderUtil.GetPropertyName(shader, i)) != null))
{
var textureName = material.GetTexture(ShaderUtil.GetPropertyName(shader, i)).name;
if (!textureNameList.Contains(textureName))
textureNameList.Add(textureName);
}
}
}
}
foreach (var textureName in textureNameList)
{
if (IsFileNameLengthTooLong(textureName))
yield return Validation.Error(string.Format("FileName '{0}' is too long. ", textureName));
}
var vrmMeta = Source.GetComponent<VRMMeta>();
if (vrmMeta != null && vrmMeta.Meta != null && vrmMeta.Meta.Thumbnail != null)
{
var thumbnailName = vrmMeta.Meta.Thumbnail.name;
if (IsFileNameLengthTooLong(thumbnailName))
yield return Validation.Error(string.Format("FileName '{0}' is too long. ", thumbnailName));
}
var meshFilters = Source.GetComponentsInChildren<MeshFilter>();
var meshesName = meshFilters.Select(x => x.sharedMesh.name).Distinct();
foreach (var meshName in meshesName)
{
if (IsFileNameLengthTooLong(meshName))
yield return Validation.Error(string.Format("FileName '{0}' is too long. ", meshName));
}
var skinnedmeshRenderers = Source.GetComponentsInChildren<SkinnedMeshRenderer>();
var skinnedmeshesName = skinnedmeshRenderers.Select(x => x.sharedMesh.name).Distinct();
foreach (var skinnedmeshName in skinnedmeshesName)
{
if (IsFileNameLengthTooLong(skinnedmeshName))
yield return Validation.Error(string.Format("FileName '{0}' is too long. ", skinnedmeshName));
}
}
/// <summary>

View File

@ -0,0 +1,48 @@
using NUnit.Framework;
using System.Linq;
using System.IO;
namespace VRM
{
public class InvalidFileNameTest
{
[Test]
[TestCase("VRMVRMVRMVRMVRMVRMVRMVRMVRMVRMVRMVRMVRMVRMVRMVRMVRMVRMVRMVRMVRMVRMV", true)]
[TestCase("VRMFormatVRMFormatVRMFormatVRMFormatVRMFormatVRMFormatVRMFormat", false)]
[TestCase("UniVRMUniVRMUniVRMUniVRMUniVRMUniVRMUniVRMUniVRMUniVRMUniVRMUniVRM", true)]
[TestCase("UniVRMUniVRMUniVRMUniVRMUniVRMUniVRMUniVRMUniVRMUniVRMUniVRMUniV", false)]
[TestCase("AliciaAliciaAliciaAliciaAliciaAliciaAliciaAliciaAliciaAliciaAliciaAlicia", true)]
public void DetectFileNameLength(string fileName, bool isIllegal)
{
var result = VRMExportSettings.IsFileNameLengthTooLong(fileName);
Assert.AreEqual(result, isIllegal);
}
[Test]
[TestCase("\u0000\u0042\u0062", true)]
[TestCase("\u0045\u0046\u0047\u0065\u0068\u0036", false)]
[TestCase("\u0043\u0045\u0047\u007F", true)]
[TestCase("\u0000\u0042\u0062", true)]
[TestCase("\u003A\u0039\u005C\u0060\u0074", false)]
[TestCase("\u005D\u006F\u001C\u007A\u0036\u0049", true)]
public void DetectControlCharacters(string fileName, bool isIllegal)
{
var result = fileName.Any(x => char.IsControl(x));
Assert.AreEqual(result, isIllegal);
}
[Test]
[TestCase("VRM|Alicia?VRM", true)]
[TestCase("UniVRMUniVRM:UniVRM", true)]
[TestCase("VRMIsVRFileFormat", false)]
[TestCase("Alicia<Alicia>Alicia", true)]
[TestCase("UniVRMIsVRMImplementationInUnityPlatform", false)]
[TestCase("Avator*Avator/Avator", true)]
public void DetectInvalidCharacters(string fileName, bool isIllegal)
{
char[] invalidPathChars = Path.GetInvalidFileNameChars();
var result = fileName.Any(x => invalidPathChars.Contains(x));
Assert.AreEqual(result, isIllegal);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8511ed091b59bca4da4fd280693b7c82
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -2,7 +2,8 @@
"name": "UniVRM.Editor.Tests",
"references": [
"VRM",
"UniJSON"
"UniJSON",
"UniVRM.Editor"
],
"optionalUnityReferences": [
"TestAssemblies"
@ -11,5 +12,9 @@
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": []
}