Huge News!Announcing our $40M Series B led by Abstract Ventures.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.2-alpha.11 to 0.4.2-alpha.12

2

dist/decoder/xmp-decoder.d.ts

@@ -6,2 +6,4 @@ import { IBufferLike, IGenericMetadata } from '../utils/types';

private _handleMatch;
private _decodeAttributeMetadata;
private _decodeElementMetadata;
private _decodeKeywords;

@@ -8,0 +10,0 @@ extractJPEG(): IBufferLike;

26

dist/decoder/xmp-decoder.js

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

const EXIF_ATTR_REGEX = /:([0-9a-z]+?)="(.*?)"$/i;
const XML_TAG_GLOBAL_REGEX = /<((xmp|exif|tiff):([0-9a-z]+?))>((.|\\s)*?)<\/\1>/gim;
const XML_TAG_REGEX = new RegExp(XML_TAG_GLOBAL_REGEX.source, 'im');
function isSimpleNumber(s) {

@@ -51,2 +53,18 @@ return /^(([1-9]\d*)|0)$/.test(s);

}
_decodeAttributeMetadata(metadata) {
const matches = this._text.match(EXIF_ATTR_GLOBAL_REGEX);
for (const attribute of matches || []) {
// tslint:disable-next-line
const [_, key, value] = attribute.match(EXIF_ATTR_REGEX) || ['', '', ''];
this._handleMatch(key, value, metadata);
}
}
_decodeElementMetadata(metadata) {
const matches = this._text.match(XML_TAG_GLOBAL_REGEX);
for (const match of matches || []) {
// tslint:disable-next-line
const [_, tagName, namespace, key, value] = match.match(XML_TAG_REGEX) || ['', '', '', '', ''];
this._handleMatch(key, value, metadata);
}
}
_decodeKeywords(genericMetadata) {

@@ -69,8 +87,4 @@ const subjectEl = findXMLTag(this._text, 'dc:subject');

const metadata = {};
const matches = this._text.match(EXIF_ATTR_GLOBAL_REGEX);
for (const match of matches || []) {
// @ts-ignore - guaranteed to match from above
const [_, key, value] = match.match(EXIF_ATTR_REGEX);
this._handleMatch(key, value, metadata);
}
this._decodeAttributeMetadata(metadata);
this._decodeElementMetadata(metadata);
this._decodeKeywords(metadata);

@@ -77,0 +91,0 @@ return metadata;

@@ -8,2 +8,3 @@ import { IGenericMetadata, IBufferLike } from '../utils/types';

private static _processEntry;
private static _findWithRegex;
private static _findExisting;

@@ -10,0 +11,0 @@ private static _findInsertionPoint;

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

const keywords_parser_1 = require("../metadata/keywords-parser");
var XMPMatchType;
(function (XMPMatchType) {
XMPMatchType["Element"] = "element";
XMPMatchType["Attribute"] = "attribute";
})(XMPMatchType || (XMPMatchType = {}));
const writableTags = Object.assign({}, tags_1.xmpTags, { DateTimeOriginal: true });

@@ -102,3 +107,2 @@ const log = log_1.createLogger('xmp-encoder');

log(`writing ${tagName} with value "${value}"`);
const replacement = XMPEncoder._buildReplacement(tagName, value);
if (existing) {

@@ -109,2 +113,3 @@ // If we have an existing value, replace the token range with our new payload

const postamble = xmpData.slice(existing.start + existing.length);
const replacement = XMPEncoder._buildReplacement(tagName, value, existing.type);
return `${preamble}${replacement}${postamble}`;

@@ -118,2 +123,3 @@ }

const postamble = xmpData.slice(insertionIndex);
const replacement = XMPEncoder._buildReplacement(tagName, value, XMPMatchType.Attribute);
const replacementWithNewline = `${BASE_NEWLINE}${replacement}`;

@@ -123,11 +129,18 @@ return `${preamble}${replacementWithNewline}${postamble}`;

}
static _findExisting(xmp, tagName) {
const regex = tagName === 'DCSubjectBagOfWords'
? /<dc:subject>(.|\s)*?<\/dc:subject>/
: new RegExp(`([a-z]+):(${tagName})="(.*?)"`, 'i');
static _findWithRegex(xmp, regex, type) {
const match = xmp.match(regex);
if (!match)
return;
return { start: match.index, length: match[0].length };
return { start: match.index, length: match[0].length, type };
}
static _findExisting(xmp, tagName) {
if (tagName === 'DCSubjectBagOfWords')
return this._findWithRegex(xmp, /<dc:subject>(.|\s)*?<\/dc:subject>/, XMPMatchType.Element);
const attributeRegex = new RegExp(`([a-z]+):(${tagName})="(.*?)"`, 'i');
const attributeMatch = this._findWithRegex(xmp, attributeRegex, XMPMatchType.Attribute);
if (attributeMatch)
return attributeMatch;
const elementRegex = new RegExp(`<([a-z]+:${tagName})(\\s*/>|(.*?)</\\1>)`, 'i');
return this._findWithRegex(xmp, elementRegex, XMPMatchType.Element);
}
static _findInsertionPoint(xmp, tagName) {

@@ -143,17 +156,22 @@ const regex = /<rdf:Description[^<]*?>/im;

}
static _buildReplacement(tagName, value) {
if (tagName === 'DateTimeOriginal')
return `exif:DateTimeOriginal="${value}"`;
if (tagName !== 'DCSubjectBagOfWords')
return `xmp:${tagName}="${value}"`;
const keywords = keywords_parser_1.parseKeywords({ DCSubjectBagOfWords: value });
if (!keywords)
throw new Error('Invalid keywords payload');
return [
`<dc:subject>`,
` <rdf:Bag>`,
...keywords.map(word => ` <rdf:li>${word.replace(/</g, '')}</rdf:li>`),
` </rdf:Bag>`,
`</dc:subject>`,
].join(BASE_NEWLINE);
static _buildReplacement(tagName, value, type) {
if (tagName === 'DCSubjectBagOfWords') {
const keywords = keywords_parser_1.parseKeywords({ DCSubjectBagOfWords: value });
if (!keywords)
throw new Error('Invalid keywords payload');
return [
`<dc:subject>`,
` <rdf:Bag>`,
...keywords.map(word => ` <rdf:li>${word.replace(/</g, '')}</rdf:li>`),
` </rdf:Bag>`,
`</dc:subject>`,
].join(BASE_NEWLINE);
}
const namespace = tagName === 'DateTimeOriginal' ? 'exif' : 'xmp';
if (type === XMPMatchType.Attribute) {
return `${namespace}:${tagName}="${value}"`;
}
else {
return `<${namespace}:${tagName}>${value}</${namespace}:${tagName}>`;
}
}

@@ -160,0 +178,0 @@ }

@@ -6,2 +6,4 @@ import {IBufferLike, IGenericMetadata, IFDTagName, XMPTagName} from '../utils/types'

const EXIF_ATTR_REGEX = /:([0-9a-z]+?)="(.*?)"$/i
const XML_TAG_GLOBAL_REGEX = /<((xmp|exif|tiff):([0-9a-z]+?))>((.|\\s)*?)<\/\1>/gim
const XML_TAG_REGEX = new RegExp(XML_TAG_GLOBAL_REGEX.source, 'im')

@@ -58,2 +60,20 @@ function isSimpleNumber(s: string): boolean {

private _decodeAttributeMetadata(metadata: IGenericMetadata): void {
const matches = this._text.match(EXIF_ATTR_GLOBAL_REGEX)
for (const attribute of matches || []) {
// tslint:disable-next-line
const [_, key, value] = attribute.match(EXIF_ATTR_REGEX) || ['', '', '']
this._handleMatch(key, value, metadata)
}
}
private _decodeElementMetadata(metadata: IGenericMetadata): void {
const matches = this._text.match(XML_TAG_GLOBAL_REGEX)
for (const match of matches || []) {
// tslint:disable-next-line
const [_, tagName, namespace, key, value] = match.match(XML_TAG_REGEX) || ['', '', '', '', '']
this._handleMatch(key, value, metadata)
}
}
private _decodeKeywords(genericMetadata: IGenericMetadata): void {

@@ -75,10 +95,4 @@ const subjectEl = findXMLTag(this._text, 'dc:subject')

const metadata: IGenericMetadata = {}
const matches = this._text.match(EXIF_ATTR_GLOBAL_REGEX)
for (const match of matches || []) {
// @ts-ignore - guaranteed to match from above
const [_, key, value] = match.match(EXIF_ATTR_REGEX)
this._handleMatch(key, value, metadata)
}
this._decodeAttributeMetadata(metadata)
this._decodeElementMetadata(metadata)
this._decodeKeywords(metadata)

@@ -85,0 +99,0 @@ return metadata

@@ -6,2 +6,13 @@ import {IGenericMetadata, IBufferLike, XMPTagName} from '../utils/types'

enum XMPMatchType {
Element = 'element',
Attribute = 'attribute',
}
interface IXMPMatch {
start: number
length: number
type: XMPMatchType
}
const writableTags: Record<XMPTagName | 'DateTimeOriginal', boolean> = {

@@ -129,3 +140,2 @@ ...xmpTags,

log(`writing ${tagName} with value "${value}"`)
const replacement = XMPEncoder._buildReplacement(tagName, value)

@@ -137,2 +147,3 @@ if (existing) {

const postamble = xmpData.slice(existing.start + existing.length)
const replacement = XMPEncoder._buildReplacement(tagName, value, existing.type)
return `${preamble}${replacement}${postamble}`

@@ -145,2 +156,3 @@ } else {

const postamble = xmpData.slice(insertionIndex)
const replacement = XMPEncoder._buildReplacement(tagName, value, XMPMatchType.Attribute)
const replacementWithNewline = `${BASE_NEWLINE}${replacement}`

@@ -151,15 +163,22 @@ return `${preamble}${replacementWithNewline}${postamble}`

private static _findExisting(
private static _findWithRegex(
xmp: string,
tagName: string,
): {start: number; length: number} | undefined {
const regex =
tagName === 'DCSubjectBagOfWords'
? /<dc:subject>(.|\s)*?<\/dc:subject>/
: new RegExp(`([a-z]+):(${tagName})="(.*?)"`, 'i')
regex: RegExp,
type: XMPMatchType,
): IXMPMatch | undefined {
const match = xmp.match(regex)
if (!match) return
return {start: match.index!, length: match[0].length}
return {start: match.index!, length: match[0].length, type}
}
private static _findExisting(xmp: string, tagName: string): IXMPMatch | undefined {
if (tagName === 'DCSubjectBagOfWords')
return this._findWithRegex(xmp, /<dc:subject>(.|\s)*?<\/dc:subject>/, XMPMatchType.Element)
const attributeRegex = new RegExp(`([a-z]+):(${tagName})="(.*?)"`, 'i')
const attributeMatch = this._findWithRegex(xmp, attributeRegex, XMPMatchType.Attribute)
if (attributeMatch) return attributeMatch
const elementRegex = new RegExp(`<([a-z]+:${tagName})(\\s*/>|(.*?)</\\1>)`, 'i')
return this._findWithRegex(xmp, elementRegex, XMPMatchType.Element)
}
private static _findInsertionPoint(

@@ -181,15 +200,23 @@ xmp: string,

value: string | number,
type: XMPMatchType,
): string {
if (tagName === 'DateTimeOriginal') return `exif:DateTimeOriginal="${value}"`
if (tagName !== 'DCSubjectBagOfWords') return `xmp:${tagName}="${value}"`
const keywords = parseKeywords({DCSubjectBagOfWords: value})
if (!keywords) throw new Error('Invalid keywords payload')
return [
`<dc:subject>`,
` <rdf:Bag>`,
...keywords.map(word => ` <rdf:li>${word.replace(/</g, '')}</rdf:li>`),
` </rdf:Bag>`,
`</dc:subject>`,
].join(BASE_NEWLINE)
if (tagName === 'DCSubjectBagOfWords') {
const keywords = parseKeywords({DCSubjectBagOfWords: value})
if (!keywords) throw new Error('Invalid keywords payload')
return [
`<dc:subject>`,
` <rdf:Bag>`,
...keywords.map(word => ` <rdf:li>${word.replace(/</g, '')}</rdf:li>`),
` </rdf:Bag>`,
`</dc:subject>`,
].join(BASE_NEWLINE)
}
const namespace = tagName === 'DateTimeOriginal' ? 'exif' : 'xmp'
if (type === XMPMatchType.Attribute) {
return `${namespace}:${tagName}="${value}"`
} else {
return `<${namespace}:${tagName}>${value}</${namespace}:${tagName}>`
}
}
}
{
"name": "@eris/exif",
"version": "0.4.2-alpha.11",
"version": "0.4.2-alpha.12",
"description": "Parses EXIF data.",

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

"@types/node": "^7.0.16",
"fast-xml-parser": "^3.16.0",
"lodash": "^4.17.4"

@@ -41,3 +42,3 @@ },

},
"gitHead": "1963467d76289070ef6e24a7d8e6e89cbc37777b"
"gitHead": "6c902c208d306b02351cb64d2e5e34598215fd74"
}

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