]> git.eshelyaron.com Git - emacs.git/commitdiff
Don't have exif bugging out on short strings
authorLars Ingebrigtsen <larsi@gnus.org>
Thu, 19 Mar 2020 15:15:04 +0000 (16:15 +0100)
committerLars Ingebrigtsen <larsi@gnus.org>
Thu, 19 Mar 2020 15:17:48 +0000 (16:17 +0100)
* lisp/image/exif.el (exif--direct-ascii-value): New function
(bug#40127).
(exif--parse-directory): Use it to get the correct values for
in-directory (i.e., shorter than 4 octets) strings.

lisp/image/exif.el
test/data/image/black-short.jpg [new file with mode: 0644]
test/lisp/image/exif-tests.el

index 642bc58321cbec1eb3f5abb831b8b3ce27aec75b..065456dc318116b034efb8fb8ea19db46f10c7e4 100644 (file)
@@ -72,7 +72,8 @@
     (283 y-resolution)
     (296 resolution-unit)
     (305 software)
-    (306 date-time))
+    (306 date-time)
+    (315 artist))
   "Alist of tag values and their names.")
 
 (defconst exif--orientation
@@ -216,7 +217,10 @@ If the orientation isn't present in the data, return nil."
                                           (+ (1+ value) length)))
                                      ;; The value is stored directly
                                      ;; in the directory.
-                                     value)
+                                     (if (eq (car field-format) 'ascii)
+                                         (exif--direct-ascii-value
+                                          value (1- length) le)
+                                       value))
                                    (car field-format)
                                    le)))))
     (let ((next (exif--read-number 4 le)))
@@ -231,6 +235,19 @@ If the orientation isn't present in the data, return nil."
         ;; We've reached the end of the directories.
         dir))))
 
+(defun exif--direct-ascii-value (value bytes le)
+  "Make VALUE into a zero-terminated string.
+VALUE is an integer representing BYTES characters."
+  (with-temp-buffer
+    (set-buffer-multibyte nil)
+    (if le
+        (dotimes (i bytes)
+          (insert (logand (lsh value (* i -8)) 255)))
+      (dotimes (i bytes)
+        (insert (logand (lsh value (* (- (1- bytes) i) -8)) 255))))
+    (insert 0)
+    (buffer-string)))
+
 (defun exif--process-value (value type le)
   "Do type-based post-processing of the value."
   (cl-case type
diff --git a/test/data/image/black-short.jpg b/test/data/image/black-short.jpg
new file mode 100644 (file)
index 0000000..02a5b0b
Binary files /dev/null and b/test/data/image/black-short.jpg differ
index cb7c9ecbda64f74270c028b36feb96571a796760..8a2231106f06f2d2b039617a38601bcdf5982b4c 100644 (file)
     (should (equal (exif-elem exif 'orientation) 1))
     (should (equal (exif-elem exif 'x-resolution) '(180 . 1)))))
 
+(ert-deftest test-exif-parse-short ()
+  (let ((exif (exif-parse-file (test-image-file "black-short.jpg"))))
+    (should (equal (exif-elem exif 'make) "thr"))
+    (should (equal (exif-elem exif 'model) "four"))
+    (should (equal (exif-elem exif 'software) "em"))
+    (should (equal (exif-elem exif 'artist) "z"))))
+
+(ert-deftest test-exit-direct-ascii-value ()
+  (equal (exif--direct-ascii-value 28005 2 t) (string ?e ?m 0))
+  (equal (exif--direct-ascii-value 28005 2 nil) (string ?m ?e 0)))
+
 ;;; exif-tests.el ends here