[web] Exif fixes and improvements (#3426)
This commit is contained in:
@@ -566,7 +566,8 @@ const RawExif: React.FC<RawExifProps> = ({
|
||||
} else if (
|
||||
tag &&
|
||||
typeof tag == "object" &&
|
||||
"description" in tag
|
||||
"description" in tag &&
|
||||
typeof tag.description == "string"
|
||||
) {
|
||||
description = tag.description;
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ import {
|
||||
import { EncryptedMagicMetadata } from "@/new/photos/types/magicMetadata";
|
||||
import { detectFileTypeInfoFromChunk } from "@/new/photos/utils/detect-type";
|
||||
import { readStream } from "@/new/photos/utils/native-stream";
|
||||
import { ensure } from "@/utils/ensure";
|
||||
import { ensure, ensureInteger, ensureNumber } from "@/utils/ensure";
|
||||
import { CustomError, handleUploadError } from "@ente/shared/error";
|
||||
import { addToCollection } from "services/collectionService";
|
||||
import {
|
||||
@@ -985,24 +985,33 @@ const extractImageOrVideoMetadata = async (
|
||||
tryParseEpochMicrosecondsFromFileName(fileName) ?? modificationTime;
|
||||
}
|
||||
|
||||
// To avoid introducing malformed data into the metadata fields (which the
|
||||
// other clients might not expect and handle), we have extra "ensure" checks
|
||||
// here that act as a safety valve if somehow the TypeScript type is lying.
|
||||
//
|
||||
// There is no deterministic sample we found that necessitated adding these
|
||||
// extra checks, but we did get one user with a list in the width field of
|
||||
// the metadata (it should've been an integer). The most probable theory is
|
||||
// that somehow it made its way in through malformed Exif.
|
||||
|
||||
const metadata: Metadata = {
|
||||
fileType,
|
||||
title: fileName,
|
||||
creationTime,
|
||||
modificationTime,
|
||||
creationTime: ensureInteger(creationTime),
|
||||
modificationTime: ensureInteger(modificationTime),
|
||||
hash,
|
||||
};
|
||||
|
||||
const location = parsedMetadataJSON?.location ?? parsedMetadata?.location;
|
||||
if (location) {
|
||||
metadata.latitude = location.latitude;
|
||||
metadata.longitude = location.longitude;
|
||||
metadata.latitude = ensureNumber(location.latitude);
|
||||
metadata.longitude = ensureNumber(location.longitude);
|
||||
}
|
||||
|
||||
if (parsedMetadata) {
|
||||
const { width: w, height: h } = parsedMetadata;
|
||||
if (w) publicMagicMetadata.w = w;
|
||||
if (h) publicMagicMetadata.h = h;
|
||||
if (w) publicMagicMetadata.w = ensureInteger(w);
|
||||
if (h) publicMagicMetadata.h = ensureInteger(h);
|
||||
}
|
||||
|
||||
return { metadata, publicMagicMetadata };
|
||||
|
||||
@@ -20,3 +20,23 @@ export const ensureString = (v: unknown): string => {
|
||||
throw new Error(`Expected a string, instead found ${String(v)}`);
|
||||
return v;
|
||||
};
|
||||
|
||||
/**
|
||||
* Throw an exception if the given value is not a number.
|
||||
*/
|
||||
export const ensureNumber = (v: unknown): number => {
|
||||
if (typeof v != "number")
|
||||
throw new Error(`Expected a number, instead found ${String(v)}`);
|
||||
return v;
|
||||
};
|
||||
|
||||
/**
|
||||
* Throw an exception if the given value is not an integral number.
|
||||
*/
|
||||
export const ensureInteger = (v: unknown): number => {
|
||||
if (typeof v != "number")
|
||||
throw new Error(`Expected a number, instead found ${String(v)}`);
|
||||
if (!Number.isInteger(v))
|
||||
throw new Error(`Expected an integer, instead found ${v}`);
|
||||
return v;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user