ref: 5c78f98021375816e6bd0e417bf618131a3d7371
parent: 739ae9a76bdb000a584c27c160a647bc0ec8a553
author: Alex Musolino <alex@musolino.id.au>
date: Tue Dec 12 10:58:17 EST 2023
exif.c: fix broken/hardcoded offsets
--- a/exif.c
+++ b/exif.c
@@ -263,9 +263,8 @@
ExifData *e;
for(e = exiftab; e->tag != 0; e++){
- if(e->tag != r->tag)
- continue;
- break;
+ if(e->tag == r->tag)
+ break;
}
if(e->show || aflag){
if(*e->str != 0){
@@ -324,7 +323,7 @@
return print(fmt, get32(r->val, bo));
}
for(i = 0; i < r->cnt; i++){
- if(pread(fd, buf, 2, r->ival + 12 + 4*i) < 0)
+ if(pread(fd, buf, 2, r->ival + 4*i) < 0)
return -1;
print(fmt, get32(buf, bo));
}
@@ -358,7 +357,7 @@
return print("%uhd %uhd", get16(r->val, bo), get16(r->val+2, bo));
}
for(i = 0; i < r->cnt; i++){
- if(pread(fd, buf, 2, r->ival + 12 + 2*i) < 0)
+ if(pread(fd, buf, 2, r->ival + 2*i) < 0)
return -1;
print("%uhd", get16(buf, bo));
}
@@ -375,7 +374,7 @@
n = sizeof(buf);
if(8*r->cnt < n)
n = 8*r->cnt;
- if((n = pread(fd, buf, n, r->ival + 12)) < 0)
+ if((n = pread(fd, buf, n, r->ival)) < 0)
return -1;
for(i = 0; i < n; i += 8){
if(i > 0)
@@ -410,7 +409,7 @@
if(suffix == nil)
suffix = "";
for(i = 0; i < r->cnt; i++){
- if(pread(fd, buf, 8, r->ival + 12 + 8*i) < 0)
+ if(pread(fd, buf, 8, r->ival + 8*i) < 0)
return -1;
if(i > 0)
print(" ");
@@ -460,7 +459,7 @@
n = sizeof(buf);
if(r->cnt < n)
n = r->cnt;
- if((n = pread(fd, buf, n, r->ival + 12)) < 0)
+ if((n = pread(fd, buf, n, r->ival)) < 0)
return -1;
return write(1, buf, n);
}
@@ -539,7 +538,7 @@
{
char buf[64];
u16int w, soi, appn, len, ver, nents;
- u32int ifdoff, exiftag, gpstag;
+ u32int segoff, ifdoff, exiftag, gpstag;
int i, bo, total;
IfdRec rec;
@@ -547,18 +546,26 @@
total = 0;
if(parse(r, bo, "www", &soi, &appn, &len) < 0)
goto Badfmt;
- if(soi != 0xffd8 || (appn & 0xfff0) != 0xffe0)
+ if(soi != 0xffd8)
goto Badfmt;
- switch(appn & 0xf){
- case 1:
- break;
- case 0:
- fprint(2, "JFIF\n");
- default:
- goto Badfmt;
+ for(;;){
+ if((appn&0xfff0) != 0xffe0)
+ goto Badfmt;
+ if((appn&0xf) == 1)
+ break;
+ if(len < 2)
+ goto Badfmt;
+ len -= 2;
+ while(len-- > 0){
+ if(Bgetc(r) < 0)
+ goto Badfmt;
+ }
+ if(parse(r, bo, "ww", &appn, &len) < 0)
+ goto Badfmt;
}
- if(Bread(r, buf, 6) != 6 || strncmp(buf, "Exif", 6) != 0)
+ if(Bread(r, buf, 6) != 6 || memcmp(buf, "Exif\0\0", 6) != 0)
goto Badfmt;
+ segoff = Boffset(r);
if(read16(r, bo, &w) < 0)
goto Badfmt;
switch(w){
@@ -584,7 +591,7 @@
memset(&rec, 0, sizeof(rec));
if(parse(r, bo, "wwWX", &rec.tag, &rec.fmt, &rec.cnt, rec.val) < 0)
goto Badfmt;
- rec.ival = get32(rec.val, bo);
+ rec.ival = segoff + get32(rec.val, bo);
switch(rec.tag){
case ExifTag:
exiftag = rec.ival;
@@ -610,7 +617,7 @@
}else
break;
}
- Bseek(r, ifdoff+12, 0);
+ Bseek(r, ifdoff, 0);
}
return total;
Badfmt: