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

@eris/exif

Package Overview
Dependencies
Maintainers
1
Versions
109
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@eris/exif - npm Package Compare versions

Comparing version 0.4.1-alpha.3 to 0.4.1-alpha.4

7

dist/decoder/ifd-entry.d.ts

@@ -1,3 +0,5 @@

import { IIFDEntry, IReader, IFDTagName } from '../utils/types';
/// <reference types="node" />
import { IIFDEntry, IReader, IFDTagName, Endian } from '../utils/types';
export declare class IFDEntry implements IIFDEntry {
startOffset: number;
tag: number;

@@ -7,3 +9,3 @@ dataType: number;

private readonly dataReader;
constructor(tag: number, dataType: number, length: number, dataReader: IReader);
constructor(startOffset: number, tag: number, dataType: number, length: number, dataReader: IReader);
readonly lengthInBytes: number;

@@ -14,2 +16,3 @@ readonly friendlyTagName: IFDTagName;

static read(reader: IReader): IFDEntry;
static mutate(buffer: Buffer, simpleEntry: IIFDEntry, data: Buffer, endianness: Endian): Buffer;
}

@@ -6,5 +6,8 @@ "use strict";

const log_1 = require("../utils/log");
const writer_1 = require("../utils/writer");
const reader_1 = require("../utils/reader");
const log = log_1.createLogger('ifd-entry');
class IFDEntry {
constructor(tag, dataType, length, dataReader) {
constructor(startOffset, tag, dataType, length, dataReader) {
this.startOffset = startOffset;
this.tag = tag;

@@ -70,2 +73,3 @@ this.dataType = dataType;

static read(reader) {
const startOffset = reader.getPosition();
const tag = reader.read(2);

@@ -76,6 +80,29 @@ const dataType = reader.read(2);

log.verbose(`read tag ${tag}`, dataReader);
return new IFDEntry(tag, dataType, length, dataReader);
return new IFDEntry(startOffset, tag, dataType, length, dataReader);
}
static mutate(buffer, simpleEntry, data, endianness) {
if (simpleEntry.dataType !== types_1.IFDDataType.String)
throw new Error('Can only mutate strings');
// Always ensure the string ends with null terminator
if (data[data.length - 1] !== 0)
data = Buffer.concat([data, Buffer.from([0])]);
// Read the real IFD so we have something better to work with
const reader = new reader_1.Reader(buffer, simpleEntry.startOffset);
reader.setEndianess(endianness);
const entry = IFDEntry.read(reader);
if (entry.lengthInBytes <= 4)
throw new Error('Can only change strings of length >3');
// Replace the length with the new length
const newLength = data.length;
const writer = new writer_1.Writer(buffer, { dangerouslyAvoidCopy: true });
writer.setEndianess(endianness);
writer.seek(entry.startOffset + 4);
writer.write(newLength, 4);
// Replace the data itself
entry.dataReader.seek(0);
const dataOffset = entry.dataReader.read(4);
return writer_1.Writer.spliceBufferRange(buffer, data, dataOffset, dataOffset + entry.lengthInBytes);
}
}
exports.IFDEntry = IFDEntry;
//# sourceMappingURL=ifd-entry.js.map

@@ -1,3 +0,5 @@

import { IGenericMetadata, IBufferLike, IJPEGOptions } from '../utils/types';
/// <reference types="node" />
import { IGenericMetadata, IBufferLike, IJPEGOptions, IIFDEntry, IFDTagName } from '../utils/types';
export declare class TIFFDecoder {
private readonly _buffer;
private readonly _reader;

@@ -15,2 +17,4 @@ private _ifds;

extractMetadata(): IGenericMetadata;
extractIFDEntries(): IIFDEntry[];
static replaceIFDEntry(decoder: TIFFDecoder, tag: IFDTagName, data: Buffer): Buffer;
}

@@ -10,5 +10,7 @@ "use strict";

const log_1 = require("../utils/log");
const ifd_entry_1 = require("./ifd-entry");
const log = log_1.createLogger('decoder');
class TIFFDecoder {
constructor(buffer) {
this._buffer = buffer;
this._reader = new reader_1.Reader(buffer);

@@ -166,4 +168,15 @@ }

}
extractIFDEntries() {
this._readAndValidateHeader();
this._readIFDs();
return this._ifds.map(ifd => ifd.entries).reduce((a, b) => a.concat(b), []);
}
static replaceIFDEntry(decoder, tag, data) {
const ifd = decoder.extractIFDEntries().find(ifd => tags_1.getFriendlyName(ifd.tag) === tag);
if (!ifd)
throw new Error(`Could not find "${tag}" in buffer`);
return ifd_entry_1.IFDEntry.mutate(Buffer.from(decoder._buffer), ifd, data, decoder._reader.getEndianess());
}
}
exports.TIFFDecoder = TIFFDecoder;
//# sourceMappingURL=tiff-decoder.js.map

@@ -6,2 +6,3 @@ "use strict";

const keywords_parser_1 = require("../metadata/keywords-parser");
const writableTags = Object.assign({}, tags_1.xmpTags, { DateTimeOriginal: true });
const log = log_1.createLogger('xmp-encoder');

@@ -55,4 +56,4 @@ const XMP_BASE_FILE = `

const tagName = key;
if (!(tagName in tags_1.xmpTags)) {
log(`skipping ${tagName} which is not an XMP tag`);
if (!(tagName in writableTags)) {
log(`skipping ${tagName} which is not a writable tag`);
continue;

@@ -140,2 +141,4 @@ }

static _buildReplacement(tagName, value) {
if (tagName === 'DateTimeOriginal')
return `exif:DateTimeOriginal="${value}"`;
if (tagName !== 'DCSubjectBagOfWords')

@@ -142,0 +145,0 @@ return `xmp:${tagName}="${value}"`;

@@ -9,2 +9,3 @@ import { IBufferLike, IReader, Endian } from '../utils/types';

getPosition(): number;
getEndianess(): Endian;
setEndianess(endian: Endian): void;

@@ -11,0 +12,0 @@ read(length: number): number;

@@ -16,2 +16,5 @@ "use strict";

}
getEndianess() {
return this._endianness;
}
setEndianess(endian) {

@@ -18,0 +21,0 @@ this._endianness = endian;

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

getPosition(): number;
getEndianess(): Endian;
setEndianess(endian: Endian): void;

@@ -46,2 +47,3 @@ read(length: number): number;

export interface IIFDEntry {
startOffset: number;
tag: number;

@@ -95,2 +97,5 @@ dataType: number;

}
export interface IWriterOptions {
dangerouslyAvoidCopy?: boolean;
}
export interface IJPEGOptions {

@@ -97,0 +102,0 @@ skipMetadata?: boolean;

@@ -1,2 +0,3 @@

import { IBufferLike, IWriter, Endian } from '../utils/types';
/// <reference types="node" />
import { IBufferLike, IWriter, Endian, IWriterOptions } from '../utils/types';
export declare class Writer implements IWriter {

@@ -6,3 +7,3 @@ private readonly _bytes;

private _endianness;
constructor(buffer?: IBufferLike);
constructor(buffer?: IBufferLike, options?: IWriterOptions);
getPosition(): number;

@@ -17,2 +18,3 @@ setEndianess(endian: Endian): void;

toBuffer(): IBufferLike;
static spliceBufferRange(buffer: Buffer, replacement: Buffer, start: number, end: number): Buffer;
}

@@ -5,8 +5,12 @@ "use strict";

class Writer {
constructor(buffer) {
constructor(buffer, options = {}) {
this._bytes = [];
this._position = 0;
this._endianness = types_1.Endian.Big;
if (buffer)
this.writeBuffer(buffer);
if (buffer) {
if (options.dangerouslyAvoidCopy)
this._bytes = buffer;
else
this.writeBuffer(buffer);
}
}

@@ -67,4 +71,9 @@ getPosition() {

}
static spliceBufferRange(buffer, replacement, start, end) {
const preamble = buffer.slice(0, start);
const postamble = buffer.slice(end);
return Buffer.concat([preamble, replacement, postamble]);
}
}
exports.Writer = Writer;
//# sourceMappingURL=writer.js.map
import {getFriendlyName} from '../utils/tags'
import {IFDDataType, IIFDEntry, IReader, IFDTagName, getDataTypeSize} from '../utils/types'
import {IFDDataType, IIFDEntry, IReader, IFDTagName, getDataTypeSize, Endian} from '../utils/types'
import {createLogger} from '../utils/log'
import {Writer} from '../utils/writer'
import {Reader} from '../utils/reader'

@@ -9,2 +11,3 @@ const log = createLogger('ifd-entry')

public constructor(
public startOffset: number,
public tag: number,

@@ -80,2 +83,3 @@ public dataType: number,

public static read(reader: IReader): IFDEntry {
const startOffset = reader.getPosition()
const tag = reader.read(2)

@@ -87,4 +91,32 @@ const dataType = reader.read(2)

log.verbose(`read tag ${tag}`, dataReader)
return new IFDEntry(tag, dataType, length, dataReader)
return new IFDEntry(startOffset, tag, dataType, length, dataReader)
}
public static mutate(
buffer: Buffer,
simpleEntry: IIFDEntry,
data: Buffer,
endianness: Endian,
): Buffer {
if (simpleEntry.dataType !== IFDDataType.String) throw new Error('Can only mutate strings')
// Always ensure the string ends with null terminator
if (data[data.length - 1] !== 0) data = Buffer.concat([data, Buffer.from([0])])
// Read the real IFD so we have something better to work with
const reader = new Reader(buffer, simpleEntry.startOffset)
reader.setEndianess(endianness)
const entry = IFDEntry.read(reader)
if (entry.lengthInBytes <= 4) throw new Error('Can only change strings of length >3')
// Replace the length with the new length
const newLength = data.length
const writer = new Writer(buffer, {dangerouslyAvoidCopy: true})
writer.setEndianess(endianness)
writer.seek(entry.startOffset + 4)
writer.write(newLength, 4)
// Replace the data itself
entry.dataReader.seek(0)
const dataOffset = entry.dataReader.read(4)
return Writer.spliceBufferRange(buffer, data, dataOffset, dataOffset + entry.lengthInBytes)
}
}

@@ -17,4 +17,7 @@ import {IFD} from '../decoder/ifd'

IJPEGOptions,
IIFDEntry,
IFDTagName,
} from '../utils/types'
import {createLogger} from '../utils/log'
import {IFDEntry} from './ifd-entry'

@@ -30,2 +33,3 @@ const log = createLogger('decoder')

export class TIFFDecoder {
private readonly _buffer: IBufferLike
private readonly _reader: IReader

@@ -37,2 +41,3 @@ private _ifds: IIFD[]

public constructor(buffer: IBufferLike) {
this._buffer = buffer
this._reader = new Reader(buffer)

@@ -209,2 +214,14 @@ }

}
public extractIFDEntries(): IIFDEntry[] {
this._readAndValidateHeader()
this._readIFDs()
return this._ifds.map(ifd => ifd.entries).reduce((a, b) => a.concat(b), [])
}
public static replaceIFDEntry(decoder: TIFFDecoder, tag: IFDTagName, data: Buffer): Buffer {
const ifd = decoder.extractIFDEntries().find(ifd => getFriendlyName(ifd.tag) === tag)
if (!ifd) throw new Error(`Could not find "${tag}" in buffer`)
return IFDEntry.mutate(Buffer.from(decoder._buffer), ifd, data, decoder._reader.getEndianess())
}
}

@@ -1,2 +0,2 @@

import {IGenericMetadata, IBufferLike} from '../utils/types'
import {IGenericMetadata, IBufferLike, XMPTagName} from '../utils/types'
import {xmpTags} from '../utils/tags'

@@ -6,2 +6,7 @@ import {createLogger} from '../utils/log'

const writableTags: Record<XMPTagName | 'DateTimeOriginal', boolean> = {
...xmpTags,
DateTimeOriginal: true,
}
const log = createLogger('xmp-encoder')

@@ -66,4 +71,4 @@

if (!(tagName in xmpTags)) {
log(`skipping ${tagName} which is not an XMP tag`)
if (!(tagName in writableTags)) {
log(`skipping ${tagName} which is not a writable tag`)
continue

@@ -174,2 +179,3 @@ }

): string {
if (tagName === 'DateTimeOriginal') return `exif:DateTimeOriginal="${value}"`
if (tagName !== 'DCSubjectBagOfWords') return `xmp:${tagName}="${value}"`

@@ -176,0 +182,0 @@ const keywords = parseKeywords({DCSubjectBagOfWords: value})

@@ -18,2 +18,6 @@ import {IBufferLike, IReader, Endian} from '../utils/types'

public getEndianess(): Endian {
return this._endianness
}
public setEndianess(endian: Endian): void {

@@ -20,0 +24,0 @@ this._endianness = endian

@@ -19,2 +19,3 @@ export interface ILogger {

getPosition(): number
getEndianess(): Endian
setEndianess(endian: Endian): void

@@ -54,2 +55,3 @@ read(length: number): number

export interface IIFDEntry {
startOffset: number
tag: number

@@ -110,2 +112,6 @@ dataType: number

export interface IWriterOptions {
dangerouslyAvoidCopy?: boolean
}
export interface IJPEGOptions {

@@ -112,0 +118,0 @@ skipMetadata?: boolean

@@ -1,9 +0,9 @@

import {IBufferLike, IWriter, Endian} from '../utils/types'
import {IBufferLike, IWriter, Endian, IWriterOptions} from '../utils/types'
export class Writer implements IWriter {
private readonly _bytes: number[]
private readonly _bytes: number[] | IBufferLike
private _position: number
private _endianness: Endian
public constructor(buffer?: IBufferLike) {
public constructor(buffer?: IBufferLike, options: IWriterOptions = {}) {
this._bytes = []

@@ -13,3 +13,6 @@ this._position = 0

if (buffer) this.writeBuffer(buffer)
if (buffer) {
if (options.dangerouslyAvoidCopy) this._bytes = buffer
else this.writeBuffer(buffer)
}
}

@@ -79,2 +82,13 @@

}
public static spliceBufferRange(
buffer: Buffer,
replacement: Buffer,
start: number,
end: number,
): Buffer {
const preamble = buffer.slice(0, start)
const postamble = buffer.slice(end)
return Buffer.concat([preamble, replacement, postamble])
}
}
{
"name": "@eris/exif",
"version": "0.4.1-alpha.3",
"version": "0.4.1-alpha.4",
"description": "Parses EXIF data.",

@@ -40,3 +40,3 @@ "main": "./dist/index.js",

},
"gitHead": "b8b08c09d1f2d26d4a5a9363866e43e340bf6c0f"
"gitHead": "411a3177ed2583d528bbf2ecc0b769f9253d34c1"
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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