New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

exifreader

Package Overview
Dependencies
Maintainers
1
Versions
97
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

exifreader - npm Package Compare versions

Comparing version 4.21.1 to 4.22.0

src/image-header-avif.js

1

exif-reader.d.ts

@@ -7,2 +7,3 @@ /// <reference types="node" />

interface FileTags {
'FileType'?: 'TIFF' | 'JPEG' | 'PNG' | 'HEIC' | 'AVIF' | 'WebP' | 'GIF',
'Bits Per Sample'?: NumberFileTag,

@@ -9,0 +10,0 @@ 'Image Height'?: NumberFileTag,

12

package.json
{
"name": "exifreader",
"version": "4.21.1",
"version": "4.22.0",
"description": "Library that parses Exif metadata in images.",

@@ -39,3 +39,3 @@ "author": "Mattias Wallander <mattias@wallander.eu>",

"eslint-plugin-cypress": "^2.15.1",
"husky": "^8.0.0",
"husky": "^9.0.11",
"mocha": "^10.2.0",

@@ -68,10 +68,10 @@ "npm-run-all": "^4.1.5",

"postinstall": "node bin/build.js --only-with-config",
"prepare": "husky install"
"prepare": "husky"
},
"nyc": {
"check-coverage": true,
"statements": 95,
"branches": 89,
"statements": 93,
"branches": 88,
"functions": 98,
"lines": 95,
"lines": 93,
"reporter": [

@@ -78,0 +78,0 @@ "lcov",

@@ -24,9 +24,11 @@ ExifReader

| JPEG | **yes** | **yes** | **yes** | **yes** | **yes** | **some**&ast; | **yes** | **yes** |
| TIFF | **yes** | **yes** | **yes** | **yes** | ??? | ??? | no | no |
| TIFF | **yes** | **yes** | **yes** | **yes** | ??? | ??? | N/A | N/A |
| PNG | **yes** | **yes** | **yes** | **yes** | ??? | ??? | no | **yes** |
| HEIC/HEIF | **yes** | no | no | **yes** | ??? | ??? | no | no |
| HEIC/HEIF | **yes** | no | **yes** | **yes** | ??? | ??? | no | no |
| AVIF | **yes** | no | **yes** | **yes** | ??? | ??? | no | no |
| WebP | **yes** | no | **yes** | **yes** | ??? | ??? | **yes** | **yes** |
| GIF | no | no | no | no | no | no | no | **yes** |
| GIF | N/A | N/A | N/A | N/A | N/A | N/A | N/A | **yes** |
- `Image details` = image width, height, etc. read from image header.
- `N/A` = The feature is not applicable to this file type.
- `???` = may be supported in any file type using Exif but it has only been tested

@@ -33,0 +35,0 @@ on JPEGs.

@@ -20,4 +20,5 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

USE_HEIC: true,
USE_AVIF: true,
USE_WEBP: true,
USE_GIF: true
};

@@ -416,2 +416,3 @@ /**

}
foundMetaData = true;
}

@@ -418,0 +419,0 @@

@@ -5,4 +5,3 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

import {getStringFromDataView} from './utils.js';
import Constants from './constants.js';
import {parseBox, findOffsets} from './image-header-iso-bmff.js';

@@ -14,2 +13,8 @@ export default {

/**
* Checks if the provided data view represents a HEIC/HEIF file.
*
* @param {DataView} dataView - The data view to check.
* @returns {boolean} True if the data view represents a HEIC/HEIF file, false otherwise.
*/
function isHeicFile(dataView) {

@@ -20,172 +25,20 @@ if (!dataView) {

const HEIC_ID = 'ftyp';
const HEIC_ID_OFFSET = 4;
const HEIC_MAJOR_BRANDS = ['heic', 'heix', 'hevc', 'hevx', 'heim', 'heis', 'hevm', 'hevs', 'mif1'];
const HEIC_MAJOR_BRAND_LENGTH = 4;
const heicMajorBrand = getStringFromDataView(dataView, HEIC_ID_OFFSET + HEIC_ID.length, HEIC_MAJOR_BRAND_LENGTH);
return (getStringFromDataView(dataView, HEIC_ID_OFFSET, HEIC_ID.length) === HEIC_ID)
&& (HEIC_MAJOR_BRANDS.indexOf(heicMajorBrand) !== -1);
try {
const headerBox = parseBox(dataView, 0);
return headerBox && HEIC_MAJOR_BRANDS.indexOf(headerBox.majorBrand) !== -1;
} catch (error) {
return false;
}
}
/**
* Finds the offsets of a HEIC file in the provided data view.
*
* @param {DataView} dataView - The data view to find offsets in.
* @returns {Object} An object containing the offsets of the TIFF header, XMP chunks, ICC chunks, and a boolean indicating if any of these exist.
*/
function findHeicOffsets(dataView) {
if (Constants.USE_EXIF || Constants.USE_ICC) {
const {offset: metaOffset, length: metaLength} = findMetaAtom(dataView);
if (metaOffset === undefined) {
return {hasAppMarkers: false};
}
const metaEndOffset = Math.min(metaOffset + metaLength, dataView.byteLength);
const {exifItemOffset, ilocOffset, colrOffset} = findMetaItems(dataView, metaOffset, metaEndOffset);
const exifOffset = findExifOffset(dataView, exifItemOffset, ilocOffset, metaEndOffset);
const iccChunks = findIccChunks(dataView, colrOffset, metaEndOffset);
return {
hasAppMarkers: (exifOffset !== undefined) || (iccChunks !== undefined),
tiffHeaderOffset: exifOffset,
iccChunks
};
}
return {hasAppMarkers: false};
return findOffsets(dataView);
}
function findMetaAtom(dataView) {
const ATOM_LENGTH_SIZE = 4;
const ATOM_TYPE_SIZE = 4;
const ATOM_MIN_LENGTH = 8;
const ATOM_TYPE_OFFSET = 4;
let offset = 0;
while (offset + ATOM_LENGTH_SIZE + ATOM_TYPE_SIZE <= dataView.byteLength) {
const atomLength = getAtomLength(dataView, offset);
if (atomLength >= ATOM_MIN_LENGTH) {
const atomType = getStringFromDataView(dataView, offset + ATOM_TYPE_OFFSET, ATOM_TYPE_SIZE);
if (atomType === 'meta') {
return {
offset,
length: atomLength
};
}
}
offset += atomLength;
}
return {
offset: undefined,
length: 0
};
}
function getAtomLength(dataView, offset) {
const ATOM_EXTENDED_SIZE_LOW_OFFSET = 12;
const atomLength = dataView.getUint32(offset);
if (extendsToEndOfFile(atomLength)) {
return dataView.byteLength - offset;
}
if (hasExtendedSize(atomLength)) {
if (hasEmptyHighBits(dataView, offset)) {
// It's a bit tricky to handle 64 bit numbers in JavaScript. Let's
// wait until there are real-world examples where it is necessary.
return dataView.getUint32(offset + ATOM_EXTENDED_SIZE_LOW_OFFSET);
}
}
return atomLength;
}
function extendsToEndOfFile(atomLength) {
return atomLength === 0;
}
function hasExtendedSize(atomLength) {
return atomLength === 1;
}
function hasEmptyHighBits(dataView, offset) {
const ATOM_EXTENDED_SIZE_OFFSET = 8;
return dataView.getUint32(offset + ATOM_EXTENDED_SIZE_OFFSET) === 0;
}
function findMetaItems(dataView, offset, metaEndOffset) {
const STRING_SIZE = 4;
const ITEM_INDEX_REL_OFFSET = -4;
const offsets = {
ilocOffset: undefined,
exifItemOffset: undefined,
colrOffset: undefined
};
while ((offset + STRING_SIZE <= metaEndOffset)
&& (!offsets.ilocOffset || !offsets.exifItemOffset || !offsets.colrOffset)) {
const itemName = getStringFromDataView(dataView, offset, STRING_SIZE);
if (Constants.USE_EXIF && (itemName === 'iloc')) {
offsets.ilocOffset = offset;
} else if (Constants.USE_EXIF && (itemName === 'Exif')) {
offsets.exifItemOffset = offset + ITEM_INDEX_REL_OFFSET;
} else if (Constants.USE_ICC && (itemName === 'colr')) {
offsets.colrOffset = offset + ITEM_INDEX_REL_OFFSET;
}
offset++;
}
return offsets;
}
function findExifOffset(dataView, exifItemOffset, offset, metaEndOffset) {
const EXIF_ITEM_OFFSET_SIZE = 2;
const ILOC_DATA_OFFSET = 12;
const EXIF_POINTER_OFFSET = 8;
const EXIF_POINTER_SIZE = 4;
const EXIF_PREFIX_LENGTH_OFFSET = 4;
const ILOC_ITEM_SIZE = 16;
if (!offset || !exifItemOffset || (exifItemOffset + EXIF_ITEM_OFFSET_SIZE > metaEndOffset)) {
return undefined;
}
const exifItemIndex = dataView.getUint16(exifItemOffset);
offset += ILOC_DATA_OFFSET;
while (offset + ILOC_ITEM_SIZE <= metaEndOffset) {
const itemIndex = dataView.getUint16(offset);
if (itemIndex === exifItemIndex) {
const exifPointer = dataView.getUint32(offset + EXIF_POINTER_OFFSET);
if (exifPointer + EXIF_POINTER_SIZE <= dataView.byteLength) {
const exifOffset = dataView.getUint32(exifPointer);
const prefixLength = exifOffset + EXIF_PREFIX_LENGTH_OFFSET;
return exifPointer + prefixLength;
}
}
offset += ILOC_ITEM_SIZE;
}
return undefined;
}
function findIccChunks(dataView, offset, metaEndOffset) {
const ITEM_TYPE_OFFSET = 8;
const ITEM_TYPE_SIZE = 4;
const ITEM_CONTENT_OFFSET = 12;
if (!offset || (offset + ITEM_CONTENT_OFFSET > metaEndOffset)) {
return undefined;
}
const colorType = getStringFromDataView(dataView, offset + ITEM_TYPE_OFFSET, ITEM_TYPE_SIZE);
if ((colorType !== 'prof') && (colorType !== 'rICC')) {
return undefined;
}
return [{
offset: offset + ITEM_CONTENT_OFFSET,
length: getAtomLength(dataView, offset) - ITEM_CONTENT_OFFSET,
chunkNumber: 1,
chunksTotal: 1
}];
}

@@ -10,2 +10,3 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

import Heic from './image-header-heic.js';
import Avif from './image-header-avif.js';
import Webp from './image-header-webp.js';

@@ -36,2 +37,6 @@ import Gif from './image-header-gif.js';

if (Constants.USE_AVIF && Avif.isAvifFile(dataView)) {
return addFileType(Avif.findAvifOffsets(dataView), 'avif', 'AVIF');
}
if (Constants.USE_WEBP && Webp.isWebpFile(dataView)) {

@@ -38,0 +43,0 @@ return addFileType(Webp.findOffsets(dataView), 'webp', 'WebP');

@@ -84,3 +84,3 @@ /* This Source Code Form is subject to the terms of the Mozilla Public

{
test: /\/(exif-reader|image-header-?(tiff|jpeg|png|heic|webp|gif)?|tags|tag-names)\.js$/,
test: /\/(exif-reader|image-header-?(tiff|jpeg|png|heic|avif|iso-bmff|webp|gif)?|tags|tag-names)\.js$/,
loader: 'string-replace-loader',

@@ -110,2 +110,3 @@ options: {

'heic',
'avif',
'webp',

@@ -112,0 +113,0 @@ 'gif'

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc