diff --git a/Assets/Scripts/ReferenceImage.cs b/Assets/Scripts/ReferenceImage.cs index 75afa786fe..251e3bdf5c 100644 --- a/Assets/Scripts/ReferenceImage.cs +++ b/Assets/Scripts/ReferenceImage.cs @@ -344,6 +344,14 @@ public bool RequestLoad(bool allowMainThread = false) // TODO Move into the async code path? var importer = new RuntimeSVGImporter(); var tex = importer.ImportAsTexture(FilePath); + + if (!ValidateDimensions(tex.width, tex.height, App.PlatformConfig.ReferenceImagesMaxDimension)) + { + m_State = ImageState.ErrorImageTooLarge; + Object.Destroy(tex); + return true; + } + ImageCache.SaveImageCache(tex, FilePath); m_ImageAspect = (float)tex.width / tex.height; int resizeLimit = App.PlatformConfig.ReferenceImagesResizeDimension; @@ -370,6 +378,14 @@ public bool RequestLoad(bool allowMainThread = false) RadianceHDRTexture hdr = new RadianceHDRTexture(fileData); Texture2D tex = new Texture2D(2, 2, TextureFormat.RGB24, false); tex = hdr.texture; + + if (!ValidateDimensions(tex.width, tex.height, App.PlatformConfig.ReferenceImagesMaxDimension)) + { + m_State = ImageState.ErrorImageTooLarge; + Object.Destroy(tex); + return true; + } + ImageCache.SaveImageCache(tex, FilePath); m_ImageAspect = (float)tex.width / tex.height; int resizeLimit = App.PlatformConfig.ReferenceImagesResizeDimension; @@ -495,6 +511,14 @@ IEnumerator RequestLoadCoroutineMainThread() // from WWW.LoadImageIntoTexture Texture2D inTex = new Texture2D(2, 2, TextureFormat.RGBA32, true); loader.LoadImageIntoTexture(inTex); + + if (!ValidateDimensions(inTex.width, inTex.height, App.PlatformConfig.ReferenceImagesMaxDimension)) + { + m_State = ImageState.ErrorImageTooLarge; + Object.Destroy(inTex); + yield break; + } + DownsizeTexture(inTex, ref m_Icon, ReferenceImageCatalog.MAX_ICON_TEX_DIMENSION); m_Icon.wrapMode = TextureWrapMode.Clamp; m_ImageAspect = (float)inTex.width / inTex.height; @@ -548,6 +572,18 @@ IEnumerable RequestLoadCoroutine() if (imageLoad != null) { ControllerConsoleScript.m_Instance.AddNewLine(imageLoad.Message, true); + if (imageLoad.imageLoadErrorCode == ImageLoadError.ImageLoadErrorCode.ImageTooLargeError) + { + m_State = ImageState.ErrorImageTooLarge; + } + else + { + m_State = ImageState.Error; + } + + reader = null; + yield break; + } } @@ -578,8 +614,6 @@ IEnumerable RequestLoadCoroutine() else { // Problem reading the file? - // images with state ImageState.Error display a generic error message 'Image failed to load' when hovering over them in the reference panel - // TODO: use more specific error messages (e.g "Too large dimensions", "Unknown format") that are set in ImageUtils.cs? (that is called by ThreadedImageReader.cs) m_State = ImageState.Error; reader = null; yield break; @@ -595,6 +629,21 @@ private bool ValidateFileSize() return info.Length <= App.PlatformConfig.ReferenceImagesMaxFileSize; } + private bool ValidateDimensions(int imageWidth, int imageHeight, int maxDimension) + { + + // Cast to long as maxDimension is big enough on desktop to overflow + if (imageWidth * imageHeight > ((long)maxDimension * (long)maxDimension)) + { + return false; + } + else + { + return true; + } + + } + public string GetExportName() { return Path.GetFileNameWithoutExtension(FileName); diff --git a/Assets/Scripts/Util/ImageUtils.cs b/Assets/Scripts/Util/ImageUtils.cs index 926e8459fb..6fa81a9bf7 100644 --- a/Assets/Scripts/Util/ImageUtils.cs +++ b/Assets/Scripts/Util/ImageUtils.cs @@ -20,8 +20,22 @@ namespace TiltBrush { + + + public class ImageLoadError : Exception { + + public enum ImageLoadErrorCode + { + // This is the default one; errors like unknown format, corruption, etc. + ImageGenericError, + // too large dimensions + ImageTooLargeError + } + + public ImageLoadErrorCode imageLoadErrorCode = ImageLoadErrorCode.ImageGenericError; + public ImageLoadError(string message) : base(message) { } public ImageLoadError(string fmt, params System.Object[] args) : base(string.Format(fmt, args)) @@ -31,6 +45,11 @@ public ImageLoadError(Exception inner, string fmt, params System.Object[] args) : base(string.Format(fmt, args), inner) { } + + public ImageLoadError(string message, ImageLoadErrorCode imageLoadErrorCode) : base(message) + { + this.imageLoadErrorCode = imageLoadErrorCode; + } } static public class ImageUtils @@ -92,7 +111,7 @@ static public void ValidateDimensions(byte[] data, int maxDimension) { throw new ImageLoadError( String.Format("Image dimensions {0}x{1} are greater than max dimensions of {2}x{2}!", - imageWidth, imageHeight, maxDimension)); + imageWidth, imageHeight, maxDimension), ImageLoadError.ImageLoadErrorCode.ImageTooLargeError); } }