[web] Exif fixes and improvements (#3426)

This commit is contained in:
Manav Rathi
2024-09-23 16:18:18 +05:30
committed by GitHub
3 changed files with 38 additions and 8 deletions

View File

@@ -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;
}

View File

@@ -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 };

View File

@@ -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;
};