From 7cf12f585758b63240a2851a74bc8267b67c749c Mon Sep 17 00:00:00 2001 From: Krishna Gupta Date: Fri, 12 Apr 2024 10:30:19 +0530 Subject: [PATCH 1/5] Scan - No error shown after selecting corrupted image. Signed-off-by: Krishna Gupta --- src/libs/fileDownload/FileUtils.ts | 19 ++++++ .../request/step/IOURequestStepScan/index.tsx | 68 +++++++++++-------- 2 files changed, 58 insertions(+), 29 deletions(-) diff --git a/src/libs/fileDownload/FileUtils.ts b/src/libs/fileDownload/FileUtils.ts index 06bd47f3b39b..1db4b8ee1583 100644 --- a/src/libs/fileDownload/FileUtils.ts +++ b/src/libs/fileDownload/FileUtils.ts @@ -1,4 +1,7 @@ +import Str from 'expensify-common/lib/str'; import {Alert, Linking, Platform} from 'react-native'; +import ImageSize from 'react-native-image-size'; +import type {FileObject} from '@components/AttachmentModal'; import DateUtils from '@libs/DateUtils'; import * as Localize from '@libs/Localize'; import Log from '@libs/Log'; @@ -238,6 +241,21 @@ function base64ToFile(base64: string, filename: string): File { return file; } +function checkIfImageIsCorrupted(file: FileObject) { + return new Promise((resolve, reject) => { + if (!Str.isImage(file.name ?? '')) { + resolve(true); + } + ImageSize.getSize(file.uri ?? '') + .then(() => { + resolve(true); + }) + .catch(() => { + reject(new Error(`'Error reading file: The file is corrupted`)); + }); + }); +} + export { showGeneralErrorAlert, showSuccessAlert, @@ -250,4 +268,5 @@ export { appendTimeToFileName, readFileAsync, base64ToFile, + checkIfImageIsCorrupted, }; diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.tsx index b9c4f866d493..3e414b9b0625 100644 --- a/src/pages/iou/request/step/IOURequestStepScan/index.tsx +++ b/src/pages/iou/request/step/IOURequestStepScan/index.tsx @@ -175,25 +175,34 @@ function IOURequestStepScan({ }; function validateReceipt(file: FileObject) { - const {fileExtension} = FileUtils.splitExtensionFromFileName(file?.name ?? ''); - if ( - !CONST.API_ATTACHMENT_VALIDATIONS.ALLOWED_RECEIPT_EXTENSIONS.includes(fileExtension.toLowerCase() as (typeof CONST.API_ATTACHMENT_VALIDATIONS.ALLOWED_RECEIPT_EXTENSIONS)[number]) - ) { - setUploadReceiptError(true, 'attachmentPicker.wrongFileType', 'attachmentPicker.notAllowedExtension'); - return false; - } + return FileUtils.checkIfImageIsCorrupted(file) + .then(() => { + const {fileExtension} = FileUtils.splitExtensionFromFileName(file?.name ?? ''); + if ( + !CONST.API_ATTACHMENT_VALIDATIONS.ALLOWED_RECEIPT_EXTENSIONS.includes( + fileExtension.toLowerCase() as (typeof CONST.API_ATTACHMENT_VALIDATIONS.ALLOWED_RECEIPT_EXTENSIONS)[number], + ) + ) { + setUploadReceiptError(true, 'attachmentPicker.wrongFileType', 'attachmentPicker.notAllowedExtension'); + return false; + } - if ((file?.size ?? 0) > CONST.API_ATTACHMENT_VALIDATIONS.MAX_SIZE) { - setUploadReceiptError(true, 'attachmentPicker.attachmentTooLarge', 'attachmentPicker.sizeExceeded'); - return false; - } + if ((file?.size ?? 0) > CONST.API_ATTACHMENT_VALIDATIONS.MAX_SIZE) { + setUploadReceiptError(true, 'attachmentPicker.attachmentTooLarge', 'attachmentPicker.sizeExceeded'); + return false; + } - if ((file?.size ?? 0) < CONST.API_ATTACHMENT_VALIDATIONS.MIN_SIZE) { - setUploadReceiptError(true, 'attachmentPicker.attachmentTooSmall', 'attachmentPicker.sizeNotMet'); - return false; - } + if ((file?.size ?? 0) < CONST.API_ATTACHMENT_VALIDATIONS.MIN_SIZE) { + setUploadReceiptError(true, 'attachmentPicker.attachmentTooSmall', 'attachmentPicker.sizeNotMet'); + return false; + } - return true; + return true; + }) + .catch(() => { + setUploadReceiptError(true, 'attachmentPicker.attachmentError', 'attachmentPicker.errorWhileSelectingCorruptedImage'); + return false; + }); } const navigateBack = () => { @@ -230,21 +239,22 @@ function IOURequestStepScan({ * Sets the Receipt objects and navigates the user to the next page */ const setReceiptAndNavigate = (file: FileObject) => { - if (!validateReceipt(file)) { - return; - } - - // Store the receipt on the transaction object in Onyx - const source = URL.createObjectURL(file as Blob); - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - IOU.setMoneyRequestReceipt(transactionID, source, file.name || '', action !== CONST.IOU.ACTION.EDIT); + validateReceipt(file).then((isFileValid) => { + if (!isFileValid) { + return; + } + // Store the receipt on the transaction object in Onyx + const source = URL.createObjectURL(file as Blob); + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + IOU.setMoneyRequestReceipt(transactionID, source, file.name || '', action !== CONST.IOU.ACTION.EDIT); - if (action === CONST.IOU.ACTION.EDIT) { - updateScanAndNavigate(file, source); - return; - } + if (action === CONST.IOU.ACTION.EDIT) { + updateScanAndNavigate(file, source); + return; + } - navigateToConfirmationStep(); + navigateToConfirmationStep(); + }); }; const setupCameraPermissionsAndCapabilities = (stream: MediaStream) => { From 3f819b83397b4c6b1d82b061b80d7370dbc9303c Mon Sep 17 00:00:00 2001 From: Krishna Gupta Date: Fri, 12 Apr 2024 13:24:48 +0530 Subject: [PATCH 2/5] fix: no error alert for corrupt image in native devices. Signed-off-by: Krishna Gupta --- .../AttachmentPicker/index.native.tsx | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/components/AttachmentPicker/index.native.tsx b/src/components/AttachmentPicker/index.native.tsx index 35638a0b604e..ef76a041d053 100644 --- a/src/components/AttachmentPicker/index.native.tsx +++ b/src/components/AttachmentPicker/index.native.tsx @@ -237,7 +237,7 @@ function AttachmentPicker({type = CONST.ATTACHMENT_PICKER_TYPE.FILE, children, s const validateAndCompleteAttachmentSelection = useCallback( (fileData: FileResponse) => { - if (fileData.width === -1 || fileData.height === -1) { + if (fileData.width === -1 || fileData.height === -1 || (fileData.height === 0 && fileData.width === 0)) { showImageCorruptionAlert(); return Promise.resolve(); } @@ -283,16 +283,20 @@ function AttachmentPicker({type = CONST.ATTACHMENT_PICKER_TYPE.FILE, children, s }; /* eslint-enable @typescript-eslint/prefer-nullish-coalescing */ if (fileDataName && Str.isImage(fileDataName)) { - ImageSize.getSize(fileDataUri).then(({width, height}) => { - fileDataObject.width = width; - fileDataObject.height = height; - validateAndCompleteAttachmentSelection(fileDataObject); - }); + ImageSize.getSize(fileDataUri) + .then(({width, height}) => { + fileDataObject.width = width; + fileDataObject.height = height; + validateAndCompleteAttachmentSelection(fileDataObject); + }) + .catch(() => { + showImageCorruptionAlert(); + }); } else { return validateAndCompleteAttachmentSelection(fileDataObject); } }, - [validateAndCompleteAttachmentSelection], + [validateAndCompleteAttachmentSelection, showImageCorruptionAlert], ); /** From 5e41d85cba0a43e2caac1bd382a575fabf4eab3d Mon Sep 17 00:00:00 2001 From: Krishna Gupta Date: Fri, 12 Apr 2024 20:01:25 +0530 Subject: [PATCH 3/5] update image validator function name. Signed-off-by: Krishna Gupta --- src/libs/fileDownload/FileUtils.ts | 18 +++++++----------- .../request/step/IOURequestStepScan/index.tsx | 2 +- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/libs/fileDownload/FileUtils.ts b/src/libs/fileDownload/FileUtils.ts index 1db4b8ee1583..d9893d93d2f6 100644 --- a/src/libs/fileDownload/FileUtils.ts +++ b/src/libs/fileDownload/FileUtils.ts @@ -241,18 +241,14 @@ function base64ToFile(base64: string, filename: string): File { return file; } -function checkIfImageIsCorrupted(file: FileObject) { +function validateImageForCorruption(file: FileObject): Promise { + if (!Str.isImage(file.name ?? '')) { + return Promise.resolve(); + } return new Promise((resolve, reject) => { - if (!Str.isImage(file.name ?? '')) { - resolve(true); - } ImageSize.getSize(file.uri ?? '') - .then(() => { - resolve(true); - }) - .catch(() => { - reject(new Error(`'Error reading file: The file is corrupted`)); - }); + .then(() => resolve()) + .catch(() => reject(new Error('Error reading file: The file is corrupted'))); }); } @@ -268,5 +264,5 @@ export { appendTimeToFileName, readFileAsync, base64ToFile, - checkIfImageIsCorrupted, + validateImageForCorruption, }; diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.tsx index 3e414b9b0625..5339b7fc14ad 100644 --- a/src/pages/iou/request/step/IOURequestStepScan/index.tsx +++ b/src/pages/iou/request/step/IOURequestStepScan/index.tsx @@ -175,7 +175,7 @@ function IOURequestStepScan({ }; function validateReceipt(file: FileObject) { - return FileUtils.checkIfImageIsCorrupted(file) + return FileUtils.validateImageForCorruption(file) .then(() => { const {fileExtension} = FileUtils.splitExtensionFromFileName(file?.name ?? ''); if ( From dc288445f1ad574e96ab0f13b08c2cd5ed20d0a6 Mon Sep 17 00:00:00 2001 From: Krishna Gupta Date: Sat, 13 Apr 2024 14:54:01 +0530 Subject: [PATCH 4/5] minor fix. Signed-off-by: Krishna Gupta --- src/components/AttachmentPicker/index.native.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/components/AttachmentPicker/index.native.tsx b/src/components/AttachmentPicker/index.native.tsx index ef76a041d053..ee4296ad95f8 100644 --- a/src/components/AttachmentPicker/index.native.tsx +++ b/src/components/AttachmentPicker/index.native.tsx @@ -289,9 +289,7 @@ function AttachmentPicker({type = CONST.ATTACHMENT_PICKER_TYPE.FILE, children, s fileDataObject.height = height; validateAndCompleteAttachmentSelection(fileDataObject); }) - .catch(() => { - showImageCorruptionAlert(); - }); + .catch(() => showImageCorruptionAlert()); } else { return validateAndCompleteAttachmentSelection(fileDataObject); } From 028748be4590aaabc9a0e0697f8b9c538800f679 Mon Sep 17 00:00:00 2001 From: Krishna Gupta Date: Mon, 15 Apr 2024 23:30:35 +0530 Subject: [PATCH 5/5] update validateAndCompleteAttachmentSelection and add comments. Signed-off-by: Krishna Gupta --- src/components/AttachmentPicker/index.native.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/AttachmentPicker/index.native.tsx b/src/components/AttachmentPicker/index.native.tsx index ee4296ad95f8..ef4d7e3e4064 100644 --- a/src/components/AttachmentPicker/index.native.tsx +++ b/src/components/AttachmentPicker/index.native.tsx @@ -237,7 +237,9 @@ function AttachmentPicker({type = CONST.ATTACHMENT_PICKER_TYPE.FILE, children, s const validateAndCompleteAttachmentSelection = useCallback( (fileData: FileResponse) => { - if (fileData.width === -1 || fileData.height === -1 || (fileData.height === 0 && fileData.width === 0)) { + // Check if the file dimensions indicate corruption + // The width/height for corrupt file is -1 on android native and 0 on ios native + if (!fileData.width || !fileData.height || (fileData.width <= 0 && fileData.height <= 0)) { showImageCorruptionAlert(); return Promise.resolve(); }