Skip to content

Commit 358c035

Browse files
HariniMalothu17Harini Malothu
andauthored
Fixed Image.getSize() to get the right size when fetching local files (#15609)
* Fix memoryStram getting unitialized * Change files * Fix GetImageSize to fetch local files * yarn:format * Make error handling better * yarn:format * Remover error handling in metro --------- Co-authored-by: Harini Malothu <hmalothu@microsoft.com>
1 parent 944694c commit 358c035

2 files changed

Lines changed: 48 additions & 15 deletions

File tree

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "none",
3+
"comment": "Fix memoryStram getting unitialized",
4+
"packageName": "react-native-windows",
5+
"email": "hmalothu@microsoft.com",
6+
"dependentChangeType": "none"
7+
}

vnext/Microsoft.ReactNative/Modules/ImageViewManagerModule.cpp

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -30,20 +30,33 @@ using namespace xaml::Media::Imaging;
3030

3131
namespace 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+
3336
winrt::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

Comments
 (0)