@@ -30,20 +30,33 @@ using namespace xaml::Media::Imaging;
3030
3131namespace Microsoft ::ReactNative {
3232
33+ static const char *ERROR_INVALID_URI = " E_INVALID_URI" ;
34+ static const char *ERROR_GET_SIZE_FAILURE = " E_GET_SIZE_FAILURE" ;
35+
3336winrt::fire_and_forget GetImageSizeAsync (
3437 const winrt::Microsoft::ReactNative::IReactPropertyBag &properties,
3538 std::string uriString,
3639 winrt::Microsoft::ReactNative::JSValue &&headers,
3740 Mso::Functor<void (int32_t width, int32_t height)> successCallback,
38- Mso::Functor<void()> errorCallback
41+ Mso::Functor<void(const char *errorCode, std::string errorMessage )> errorCallback
3942#ifdef USE_FABRIC
4043 ,
4144 bool useFabric
4245#endif // USE_FABRIC
4346) {
4447 bool succeeded{false };
48+ const char *errorCode = ERROR_GET_SIZE_FAILURE ;
49+ std::string errorMessage;
4550
4651 try {
52+ // Validate URI is not empty
53+ if (uriString.empty ()) {
54+ errorCode = ERROR_INVALID_URI ;
55+ errorMessage = " Cannot get the size of an image for an empty URI" ;
56+ errorCallback (errorCode, errorMessage);
57+ co_return ;
58+ }
59+
4760 ReactImageSource source;
4861 source.uri = uriString;
4962 if (!headers.IsNull ()) {
@@ -56,9 +69,10 @@ winrt::fire_and_forget GetImageSizeAsync(
5669 winrt::hstring scheme{uri.SchemeName ()};
5770 bool needsDownload = (scheme == L" http" ) || (scheme == L" https" );
5871 bool inlineData = scheme == L" data" ;
72+ bool isLocalFile = (scheme == L" file" ) || (scheme == L" ms-appx" ) || (scheme == L" ms-appdata" );
5973
6074 winrt::IRandomAccessStream memoryStream;
61- if (needsDownload) {
75+ if (needsDownload || isLocalFile ) {
6276 memoryStream = co_await GetImageStreamAsync (properties, source);
6377 } else if (inlineData) {
6478 memoryStream = co_await GetImageInlineDataAsync (source);
@@ -77,23 +91,31 @@ winrt::fire_and_forget GetImageSizeAsync(
7791 }
7892#ifdef USE_FABRIC
7993 } else {
80- auto result = wicBitmapSourceFromStream (memoryStream);
81- if (!std::get<std::shared_ptr<facebook::react::ImageErrorInfo>>(result)) {
82- auto imagingFactory = std::get<winrt::com_ptr<IWICImagingFactory>>(result);
83- auto wicBmpSource = std::get<winrt::com_ptr<IWICBitmapSource>>(result);
84- UINT width, height;
85- if (SUCCEEDED (wicBmpSource->GetSize (&width, &height))) {
86- successCallback (width, height);
87- succeeded = true ;
94+ if (memoryStream) { // Added nullcheck to prevent app from crashing if value is uninitialized
95+ auto result = wicBitmapSourceFromStream (memoryStream);
96+ if (!std::get<std::shared_ptr<facebook::react::ImageErrorInfo>>(result)) {
97+ auto imagingFactory = std::get<winrt::com_ptr<IWICImagingFactory>>(result);
98+ auto wicBmpSource = std::get<winrt::com_ptr<IWICBitmapSource>>(result);
99+ UINT width, height;
100+ if (SUCCEEDED (wicBmpSource->GetSize (&width, &height))) {
101+ successCallback (width, height);
102+ succeeded = true ;
103+ }
88104 }
89105 }
90106 }
91107#endif // USE_FABRIC
92- } catch (winrt::hresult_error const &) {
108+ } catch (winrt::hresult_error const &e) {
109+ errorMessage = " Failed to get image size: " + Microsoft::Common::Unicode::Utf16ToUtf8 (std::wstring (e.message ())) +
110+ " for URI: " + uriString;
93111 }
94112
95- if (!succeeded)
96- errorCallback ();
113+ if (!succeeded) {
114+ if (errorMessage.empty ()) {
115+ errorMessage = " Failed to get image size for URI: " + uriString;
116+ }
117+ errorCallback (errorCode, errorMessage);
118+ }
97119
98120 co_return ;
99121}
@@ -112,7 +134,9 @@ void ImageLoader::getSize(std::string uri, React::ReactPromise<std::vector<doubl
112134 [result](double width, double height) noexcept {
113135 result.Resolve (std::vector<double >{width, height});
114136 },
115- [result]() noexcept { result.Reject (" Failed" ); }
137+ [result](const char *errorCode, std::string errorMessage) noexcept {
138+ result.Reject (React::ReactError{errorCode, errorMessage});
139+ }
116140#ifdef USE_FABRIC
117141 ,
118142 IsFabricEnabled (context.Properties ().Handle ())
@@ -137,7 +161,9 @@ void ImageLoader::getSizeWithHeaders(
137161 [result](double width, double height) noexcept {
138162 result.Resolve (Microsoft::ReactNativeSpecs::ImageLoaderIOSSpec_getSizeWithHeaders_returnType{width, height});
139163 },
140- [result]() noexcept { result.Reject (" Failed" ); }
164+ [result](const char *errorCode, std::string errorMessage) noexcept {
165+ result.Reject (React::ReactError{errorCode, errorMessage});
166+ }
141167#ifdef USE_FABRIC
142168 ,
143169 IsFabricEnabled (context.Properties ().Handle ())
0 commit comments