Skip to content

Commit

Permalink
Reject ExifTime values of "0" or "00" (seen on some Canon images)
Browse files Browse the repository at this point in the history
  • Loading branch information
mceachen committed Sep 7, 2023
1 parent 23a7d96 commit b05c39d
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 16 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ vendored versions of ExifTool match the version that they vendor.

## Version history

### v22.2.1

- 🐞 `ExifTime` now properly rejects invalid `SubSecTime`, `SubSecTimeOriginal`, ... values of "0" or "00".

### v22.2.0

- ✨ Add support for zone extraction from `ExifDateTime`, `ExifTime`, `number[]`, and `number` fields.
Expand Down
30 changes: 15 additions & 15 deletions docs/classes/ExifTime.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ <h4>Hierarchy</h4>
<ul class="tsd-hierarchy">
<li><span class="target">ExifTime</span></li></ul></section><aside class="tsd-sources">
<ul>
<li>Defined in <a href="https://github.com/photostructure/exiftool-vendored.js/blob/main/src/ExifTime.ts#L8">src/ExifTime.ts:8</a></li></ul></aside>
<li>Defined in <a href="https://github.com/photostructure/exiftool-vendored.js/blob/main/src/ExifTime.ts#L13">src/ExifTime.ts:13</a></li></ul></aside>
<section class="tsd-panel-group tsd-index-group">
<section class="tsd-panel tsd-index-panel">
<details class="tsd-index-content tsd-index-accordion" open><summary class="tsd-accordion-summary tsd-index-summary">
Expand Down Expand Up @@ -78,34 +78,34 @@ <h5><code class="tsd-tag ts-flagOptional">Optional</code> <span class="tsd-kind-
<h5><code class="tsd-tag ts-flagOptional">Optional</code> <span class="tsd-kind-parameter">rawValue</span>: <span class="tsd-signature-type">string</span></h5></li></ul></div>
<h4 class="tsd-returns-title">Returns <a href="ExifTime.html" class="tsd-signature-type tsd-kind-class">ExifTime</a></h4><aside class="tsd-sources">
<ul>
<li>Defined in <a href="https://github.com/photostructure/exiftool-vendored.js/blob/main/src/ExifTime.ts#L25">src/ExifTime.ts:25</a></li></ul></aside></li></ul></section></section>
<li>Defined in <a href="https://github.com/photostructure/exiftool-vendored.js/blob/main/src/ExifTime.ts#L30">src/ExifTime.ts:30</a></li></ul></aside></li></ul></section></section>
<section class="tsd-panel-group tsd-member-group">
<h2>Properties</h2>
<section class="tsd-panel tsd-member"><a id="hour" class="tsd-anchor"></a>
<h3 class="tsd-anchor-link"><code class="tsd-tag ts-flagReadonly">Readonly</code> <span>hour</span><a href="#hour" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="#icon-anchor"></use></svg></a></h3>
<div class="tsd-signature"><span class="tsd-kind-property">hour</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">number</span></div><aside class="tsd-sources">
<ul>
<li>Defined in <a href="https://github.com/photostructure/exiftool-vendored.js/blob/main/src/ExifTime.ts#L26">src/ExifTime.ts:26</a></li></ul></aside></section>
<li>Defined in <a href="https://github.com/photostructure/exiftool-vendored.js/blob/main/src/ExifTime.ts#L31">src/ExifTime.ts:31</a></li></ul></aside></section>
<section class="tsd-panel tsd-member"><a id="millisecond" class="tsd-anchor"></a>
<h3 class="tsd-anchor-link"><code class="tsd-tag ts-flagOptional">Optional</code> <code class="tsd-tag ts-flagReadonly">Readonly</code> <span>millisecond</span><a href="#millisecond" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="#icon-anchor"></use></svg></a></h3>
<div class="tsd-signature"><span class="tsd-kind-property">millisecond</span><span class="tsd-signature-symbol">?:</span> <span class="tsd-signature-type">number</span></div><aside class="tsd-sources">
<ul>
<li>Defined in <a href="https://github.com/photostructure/exiftool-vendored.js/blob/main/src/ExifTime.ts#L29">src/ExifTime.ts:29</a></li></ul></aside></section>
<li>Defined in <a href="https://github.com/photostructure/exiftool-vendored.js/blob/main/src/ExifTime.ts#L34">src/ExifTime.ts:34</a></li></ul></aside></section>
<section class="tsd-panel tsd-member"><a id="minute" class="tsd-anchor"></a>
<h3 class="tsd-anchor-link"><code class="tsd-tag ts-flagReadonly">Readonly</code> <span>minute</span><a href="#minute" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="#icon-anchor"></use></svg></a></h3>
<div class="tsd-signature"><span class="tsd-kind-property">minute</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">number</span></div><aside class="tsd-sources">
<ul>
<li>Defined in <a href="https://github.com/photostructure/exiftool-vendored.js/blob/main/src/ExifTime.ts#L27">src/ExifTime.ts:27</a></li></ul></aside></section>
<li>Defined in <a href="https://github.com/photostructure/exiftool-vendored.js/blob/main/src/ExifTime.ts#L32">src/ExifTime.ts:32</a></li></ul></aside></section>
<section class="tsd-panel tsd-member"><a id="rawValue" class="tsd-anchor"></a>
<h3 class="tsd-anchor-link"><code class="tsd-tag ts-flagOptional">Optional</code> <code class="tsd-tag ts-flagReadonly">Readonly</code> <span>raw<wbr/>Value</span><a href="#rawValue" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="#icon-anchor"></use></svg></a></h3>
<div class="tsd-signature"><span class="tsd-kind-property">raw<wbr/>Value</span><span class="tsd-signature-symbol">?:</span> <span class="tsd-signature-type">string</span></div><aside class="tsd-sources">
<ul>
<li>Defined in <a href="https://github.com/photostructure/exiftool-vendored.js/blob/main/src/ExifTime.ts#L30">src/ExifTime.ts:30</a></li></ul></aside></section>
<li>Defined in <a href="https://github.com/photostructure/exiftool-vendored.js/blob/main/src/ExifTime.ts#L35">src/ExifTime.ts:35</a></li></ul></aside></section>
<section class="tsd-panel tsd-member"><a id="second" class="tsd-anchor"></a>
<h3 class="tsd-anchor-link"><code class="tsd-tag ts-flagReadonly">Readonly</code> <span>second</span><a href="#second" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="#icon-anchor"></use></svg></a></h3>
<div class="tsd-signature"><span class="tsd-kind-property">second</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">number</span></div><aside class="tsd-sources">
<ul>
<li>Defined in <a href="https://github.com/photostructure/exiftool-vendored.js/blob/main/src/ExifTime.ts#L28">src/ExifTime.ts:28</a></li></ul></aside></section></section>
<li>Defined in <a href="https://github.com/photostructure/exiftool-vendored.js/blob/main/src/ExifTime.ts#L33">src/ExifTime.ts:33</a></li></ul></aside></section></section>
<section class="tsd-panel-group tsd-member-group">
<h2>Accessors</h2>
<section class="tsd-panel tsd-member"><a id="millis" class="tsd-anchor"></a>
Expand All @@ -115,7 +115,7 @@ <h3 class="tsd-anchor-link"><span>millis</span><a href="#millis" aria-label="Per
<li class="tsd-description">
<h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">undefined</span><span class="tsd-signature-symbol"> | </span><span class="tsd-signature-type">number</span></h4><aside class="tsd-sources">
<ul>
<li>Defined in <a href="https://github.com/photostructure/exiftool-vendored.js/blob/main/src/ExifTime.ts#L33">src/ExifTime.ts:33</a></li></ul></aside></li></ul></section></section>
<li>Defined in <a href="https://github.com/photostructure/exiftool-vendored.js/blob/main/src/ExifTime.ts#L38">src/ExifTime.ts:38</a></li></ul></aside></li></ul></section></section>
<section class="tsd-panel-group tsd-member-group">
<h2>Methods</h2>
<section class="tsd-panel tsd-member"><a id="toExifString" class="tsd-anchor"></a>
Expand All @@ -125,15 +125,15 @@ <h3 class="tsd-anchor-link"><span>to<wbr/>Exif<wbr/>String</span><a href="#toExi
<li class="tsd-description">
<h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">string</span></h4><aside class="tsd-sources">
<ul>
<li>Defined in <a href="https://github.com/photostructure/exiftool-vendored.js/blob/main/src/ExifTime.ts#L51">src/ExifTime.ts:51</a></li></ul></aside></li></ul></section>
<li>Defined in <a href="https://github.com/photostructure/exiftool-vendored.js/blob/main/src/ExifTime.ts#L56">src/ExifTime.ts:56</a></li></ul></aside></li></ul></section>
<section class="tsd-panel tsd-member"><a id="toISOString" class="tsd-anchor"></a>
<h3 class="tsd-anchor-link"><span>toISOString</span><a href="#toISOString" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="#icon-anchor"></use></svg></a></h3>
<ul class="tsd-signatures">
<li class="tsd-signature tsd-anchor-link" id="toISOString.toISOString-1"><span class="tsd-kind-call-signature">toISOString</span><span class="tsd-signature-symbol">(</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">string</span><a href="#toISOString.toISOString-1" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="#icon-anchor"></use></svg></a></li>
<li class="tsd-description">
<h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">string</span></h4><aside class="tsd-sources">
<ul>
<li>Defined in <a href="https://github.com/photostructure/exiftool-vendored.js/blob/main/src/ExifTime.ts#L47">src/ExifTime.ts:47</a></li></ul></aside></li></ul></section>
<li>Defined in <a href="https://github.com/photostructure/exiftool-vendored.js/blob/main/src/ExifTime.ts#L52">src/ExifTime.ts:52</a></li></ul></aside></li></ul></section>
<section class="tsd-panel tsd-member"><a id="toJSON" class="tsd-anchor"></a>
<h3 class="tsd-anchor-link"><span>toJSON</span><a href="#toJSON" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="#icon-anchor"></use></svg></a></h3>
<ul class="tsd-signatures">
Expand All @@ -154,15 +154,15 @@ <h5><span class="tsd-kind-property">raw<wbr/>Value</span><span class="tsd-signat
<li class="tsd-parameter">
<h5><span class="tsd-kind-property">second</span><span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">number</span></h5></li></ul><aside class="tsd-sources">
<ul>
<li>Defined in <a href="https://github.com/photostructure/exiftool-vendored.js/blob/main/src/ExifTime.ts#L55">src/ExifTime.ts:55</a></li></ul></aside></li></ul></section>
<li>Defined in <a href="https://github.com/photostructure/exiftool-vendored.js/blob/main/src/ExifTime.ts#L60">src/ExifTime.ts:60</a></li></ul></aside></li></ul></section>
<section class="tsd-panel tsd-member"><a id="toString" class="tsd-anchor"></a>
<h3 class="tsd-anchor-link"><span>to<wbr/>String</span><a href="#toString" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="#icon-anchor"></use></svg></a></h3>
<ul class="tsd-signatures">
<li class="tsd-signature tsd-anchor-link" id="toString.toString-1"><span class="tsd-kind-call-signature">to<wbr/>String</span><span class="tsd-signature-symbol">(</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">string</span><a href="#toString.toString-1" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="#icon-anchor"></use></svg></a></li>
<li class="tsd-description">
<h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">string</span></h4><aside class="tsd-sources">
<ul>
<li>Defined in <a href="https://github.com/photostructure/exiftool-vendored.js/blob/main/src/ExifTime.ts#L43">src/ExifTime.ts:43</a></li></ul></aside></li></ul></section>
<li>Defined in <a href="https://github.com/photostructure/exiftool-vendored.js/blob/main/src/ExifTime.ts#L48">src/ExifTime.ts:48</a></li></ul></aside></li></ul></section>
<section class="tsd-panel tsd-member"><a id="fromDateTime" class="tsd-anchor"></a>
<h3 class="tsd-anchor-link"><code class="tsd-tag ts-flagStatic">Static</code> <span>from<wbr/>Date<wbr/>Time</span><a href="#fromDateTime" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="#icon-anchor"></use></svg></a></h3>
<ul class="tsd-signatures">
Expand All @@ -177,7 +177,7 @@ <h5><span class="tsd-kind-parameter">dt</span>: <span class="tsd-signature-type
<h5><code class="tsd-tag ts-flagOptional">Optional</code> <span class="tsd-kind-parameter">rawValue</span>: <span class="tsd-signature-type">string</span></h5></li></ul></div>
<h4 class="tsd-returns-title">Returns <a href="../types/Maybe.html" class="tsd-signature-type tsd-kind-type-alias">Maybe</a><span class="tsd-signature-symbol">&lt;</span><a href="ExifTime.html" class="tsd-signature-type tsd-kind-class">ExifTime</a><span class="tsd-signature-symbol">&gt;</span></h4><aside class="tsd-sources">
<ul>
<li>Defined in <a href="https://github.com/photostructure/exiftool-vendored.js/blob/main/src/ExifTime.ts#L19">src/ExifTime.ts:19</a></li></ul></aside></li></ul></section>
<li>Defined in <a href="https://github.com/photostructure/exiftool-vendored.js/blob/main/src/ExifTime.ts#L24">src/ExifTime.ts:24</a></li></ul></aside></li></ul></section>
<section class="tsd-panel tsd-member"><a id="fromEXIF" class="tsd-anchor"></a>
<h3 class="tsd-anchor-link"><code class="tsd-tag ts-flagStatic">Static</code> <span>fromEXIF</span><a href="#fromEXIF" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="#icon-anchor"></use></svg></a></h3>
<ul class="tsd-signatures">
Expand All @@ -190,7 +190,7 @@ <h4 class="tsd-parameters-title">Parameters</h4>
<h5><span class="tsd-kind-parameter">text</span>: <span class="tsd-signature-type">string</span></h5></li></ul></div>
<h4 class="tsd-returns-title">Returns <a href="../types/Maybe.html" class="tsd-signature-type tsd-kind-type-alias">Maybe</a><span class="tsd-signature-symbol">&lt;</span><a href="ExifTime.html" class="tsd-signature-type tsd-kind-class">ExifTime</a><span class="tsd-signature-symbol">&gt;</span></h4><aside class="tsd-sources">
<ul>
<li>Defined in <a href="https://github.com/photostructure/exiftool-vendored.js/blob/main/src/ExifTime.ts#L9">src/ExifTime.ts:9</a></li></ul></aside></li></ul></section>
<li>Defined in <a href="https://github.com/photostructure/exiftool-vendored.js/blob/main/src/ExifTime.ts#L14">src/ExifTime.ts:14</a></li></ul></aside></li></ul></section>
<section class="tsd-panel tsd-member"><a id="fromJSON" class="tsd-anchor"></a>
<h3 class="tsd-anchor-link"><code class="tsd-tag ts-flagStatic">Static</code> <span>fromJSON</span><a href="#fromJSON" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="#icon-anchor"></use></svg></a></h3>
<ul class="tsd-signatures">
Expand All @@ -216,7 +216,7 @@ <h5><span class="tsd-kind-property">raw<wbr/>Value</span><span class="tsd-signat
<h5><span class="tsd-kind-property">second</span><span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">number</span></h5></li></ul></li></ul></div>
<h4 class="tsd-returns-title">Returns <a href="ExifTime.html" class="tsd-signature-type tsd-kind-class">ExifTime</a></h4><aside class="tsd-sources">
<ul>
<li>Defined in <a href="https://github.com/photostructure/exiftool-vendored.js/blob/main/src/ExifTime.ts#L66">src/ExifTime.ts:66</a></li></ul></aside></li></ul></section></section></div>
<li>Defined in <a href="https://github.com/photostructure/exiftool-vendored.js/blob/main/src/ExifTime.ts#L71">src/ExifTime.ts:71</a></li></ul></aside></li></ul></section></section></div>
<div class="col-sidebar">
<div class="page-menu">
<div class="tsd-navigation settings">
Expand Down
8 changes: 8 additions & 0 deletions src/ExifTime.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,12 @@ describe("ExifTime", () => {
it("renders EXIF for 01:02:03", () => {
expect(toExifString(new ExifTime(1, 2, 3))).to.eql("01:02:03")
})

describe("rejects invalid raw values", () => {
for (const ea of [null, undefined, "", " ", "0", "00", "a"]) {
it(`rejects ${JSON.stringify(ea)}`, () => {
expect(ExifTime.fromEXIF(ea as any)).to.eql(undefined)
})
}
})
})
7 changes: 6 additions & 1 deletion src/ExifTime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,18 @@ import { DateTime } from "luxon"
import { first, map, Maybe } from "./Maybe"
import { blank, pad2, pad3, toS } from "./String"

// Reject times whose raw value is "0" or "00". TODO: We may want to reject
// "00:00", but midnight is a valid time--we'd have to reject 00:00 only if we
// could be certain this photo wasn't taken exactly at midnight.
const onlyZerosRE = /^0+$/

/**
* Encodes an ExifTime (which may not have a timezone offset)
*/
export class ExifTime {
static fromEXIF(text: string): Maybe<ExifTime> {
if (blank(text)) return
text = toS(text).trim()
if (blank(text) || onlyZerosRE.test(text)) return
return first(
["HH:mm:ss.uZZ", "HH:mm:ssZZ", "HH:mm:ss.u", "HH:mm:ss"],
(fmt) =>
Expand Down

0 comments on commit b05c39d

Please sign in to comment.