mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Fix attempt: Check cloud project before sending it to avoid corrupt cloud project (#5183)
This commit is contained in:
@@ -2117,7 +2117,6 @@ const MainFrame = (props: Props) => {
|
||||
}));
|
||||
}
|
||||
} catch (rawError) {
|
||||
// If any error happens, ensure we hide the snackbars.
|
||||
_closeSnackMessage();
|
||||
const errorMessage = getWriteErrorMessage
|
||||
? getWriteErrorMessage(rawError)
|
||||
@@ -2272,11 +2271,12 @@ const MainFrame = (props: Props) => {
|
||||
} catch (rawError) {
|
||||
showErrorBox({
|
||||
message: i18n._(
|
||||
t`Unable to save as the project! Please try again by choosing another location.`
|
||||
t`Unable to save the project! Please try again later or save the project in another location.`
|
||||
),
|
||||
rawError,
|
||||
errorId: 'project-save-error',
|
||||
});
|
||||
_closeSnackMessage();
|
||||
} finally {
|
||||
setIsSavingProject(false);
|
||||
}
|
||||
@@ -2288,6 +2288,7 @@ const MainFrame = (props: Props) => {
|
||||
currentFileMetadata,
|
||||
getStorageProviderOperations,
|
||||
_showSnackMessage,
|
||||
_closeSnackMessage,
|
||||
_replaceSnackMessage,
|
||||
i18n,
|
||||
unsavedChanges,
|
||||
|
@@ -13,11 +13,33 @@ import type { MessageDescriptor } from '../../Utils/i18n/MessageDescriptor.flow'
|
||||
import { serializeToJSON } from '../../Utils/Serializer';
|
||||
import CloudSaveAsDialog from './CloudSaveAsDialog';
|
||||
import { t } from '@lingui/macro';
|
||||
import { createZipWithSingleTextFile } from '../../Utils/Zip.js/Utils';
|
||||
import {
|
||||
createZipWithSingleTextFile,
|
||||
unzipFirstEntryOfBlob,
|
||||
} from '../../Utils/Zip.js/Utils';
|
||||
|
||||
const zipProject = async (project: gdProject) => {
|
||||
const zipProject = async (project: gdProject): Promise<[Blob, string]> => {
|
||||
const projectJson = serializeToJSON(project);
|
||||
return createZipWithSingleTextFile(projectJson, 'game.json');
|
||||
const zippedProject = await createZipWithSingleTextFile(
|
||||
projectJson,
|
||||
'game.json'
|
||||
);
|
||||
return [zippedProject, projectJson];
|
||||
};
|
||||
|
||||
const checkZipContent = async (
|
||||
zip: Blob,
|
||||
projectJson: string
|
||||
): Promise<boolean> => {
|
||||
try {
|
||||
const unzippedProjectJson = await unzipFirstEntryOfBlob(zip);
|
||||
return (
|
||||
unzippedProjectJson === projectJson && !!JSON.parse(unzippedProjectJson)
|
||||
);
|
||||
} catch (error) {
|
||||
console.error('An error occurred when checking zipped project.', error);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
const zipProjectAndCommitVersion = async ({
|
||||
@@ -31,11 +53,15 @@ const zipProjectAndCommitVersion = async ({
|
||||
cloudProjectId: string,
|
||||
options?: {| previousVersion: string |},
|
||||
|}): Promise<?string> => {
|
||||
const archive = await zipProject(project);
|
||||
const [zippedProject, projectJson] = await zipProject(project);
|
||||
const archiveIsSane = await checkZipContent(zippedProject, projectJson);
|
||||
if (!archiveIsSane) {
|
||||
throw new Error('Project compression failed before saving the project.');
|
||||
}
|
||||
const newVersion = await commitVersion({
|
||||
authenticatedUser,
|
||||
cloudProjectId,
|
||||
zippedProject: archive,
|
||||
zippedProject,
|
||||
previousVersion: options ? options.previousVersion : null,
|
||||
});
|
||||
return newVersion;
|
||||
|
@@ -72,7 +72,9 @@ function ConfirmDeleteDialog(props: Props) {
|
||||
]}
|
||||
noMobileFullScreen
|
||||
>
|
||||
<Text size="body">{i18n._(props.message)}</Text>
|
||||
<Text size="body" style={{ userSelect: 'text' }}>
|
||||
{i18n._(props.message)}
|
||||
</Text>
|
||||
<LargeSpacer />
|
||||
<TextField
|
||||
autoFocus="desktop"
|
||||
|
@@ -47,6 +47,9 @@ type Props = {|
|
||||
whiteSpace?: 'nowrap' | 'pre-wrap',
|
||||
textOverflow?: 'ellipsis',
|
||||
|
||||
// Allow user to select text
|
||||
userSelect?: 'text',
|
||||
|
||||
// Allow to expand the text
|
||||
flex?: 1,
|
||||
|
||||
|
@@ -2,7 +2,9 @@
|
||||
|
||||
import { initializeZipJs } from '.';
|
||||
|
||||
export const unzipFirstEntryOfBlob = async (zippedBlob: Blob) => {
|
||||
export const unzipFirstEntryOfBlob = async (
|
||||
zippedBlob: Blob
|
||||
): Promise<string> => {
|
||||
const zipJs: ZipJs = await initializeZipJs();
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
|
Reference in New Issue
Block a user