shithub: qk1

Download patch

ref: c03ebff7de31f1208b35130e36be60f7c774ba2d
parent: 6edeaf06f5e6abd2c1e8f41f0ec0517abb43f613
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Tue Dec 26 21:48:45 EST 2023

wav: apparently fmt doesn't _always_ come after WAVE

--- a/wav.c
+++ b/wav.c
@@ -24,30 +24,8 @@
 		return -1;
 	}
 	p += 4; sz -= 4;
-	if(memcmp(p, "fmt ", 4) != 0){
-		werrstr("no \"fmt \" subchunk");
-		return -1;
-	}
-	p += 4; sz -= 4;
-	n = le32(p); sz -= 4;
-
-	fmt = le16(p); sz -= 2; n -= 2;
-	if(fmt != 1){
-		werrstr("not Microsoft PCM format: %d", fmt);
-		return -1;
-	}
-	info->channels = le16(p); sz -= 2; n -= 2;
-	info->rate = le32(p); sz -= 4; n -= 4;
-	p += 4+2; sz -= 4+2; n -= 4+2; /* skip ByteRate + BlockAlign */
-	info->width = le16(p); sz -= 2; n -= 2;
-	if((info->width % 8) != 0){
-		werrstr("invalid width: %d", info->width);
-		return -1;
-	}
-	info->width /= 8;
-	info->loopofs = -1;
 	loopsamples = 0;
-	p += n; sz -= n;
+	info->loopofs = -1;
 
 	for(; sz >= 8;){
 		p += 4; sz -= 4;
@@ -54,33 +32,53 @@
 		n = le32(p); sz -= 4;
 		if(n > sz || n <= 0)
 			break;
-		if(n >= 4){
-			if(memcmp(p-8, "cue ", 4) == 0){
-				i = le32(p); sz -= 4; n -= 4; /* CuePoints - usually two of those */
-				if(i >= 1 && n >= i*6*4){
+		if(n < 4)
+			goto skip;
+		if(memcmp(p-8, "fmt ", 4) == 0){
+			fmt = le16(p); sz -= 2; n -= 2;
+			if(fmt != 1){
+				werrstr("not Microsoft PCM format: %d", fmt);
+				return -1;
+			}
+			info->channels = le16(p); sz -= 2; n -= 2;
+			info->rate = le32(p); sz -= 4; n -= 4;
+			p += 4+2; sz -= 4+2; n -= 4+2; /* skip ByteRate + BlockAlign */
+			info->width = le16(p); sz -= 2; n -= 2;
+			if((info->width % 8) != 0){
+				werrstr("invalid width: %d", info->width);
+				return -1;
+			}
+			info->width /= 8;
+		}else if(memcmp(p-8, "cue ", 4) == 0){
+			i = le32(p); sz -= 4; n -= 4; /* CuePoints - usually two of those */
+			if(i >= 1 && n >= i*6*4){
+				p += 5*4; sz -= 5*4; n -= 5*4; /* Name+Position+Chunk+ChunkStart+BlockStart */
+				info->loopofs = le32(p); sz -= 4; n -= 4;
+				/* FIXME(sigrid): check if this is needed and whether it works at all */
+				if(i > 1){
 					p += 5*4; sz -= 5*4; n -= 5*4; /* Name+Position+Chunk+ChunkStart+BlockStart */
-					info->loopofs = le32(p); sz -= 4; n -= 4;
-					/* FIXME(sigrid): check if this is needed and whether it works at all */
-					if(i > 1){
-						p += 5*4; sz -= 5*4; n -= 5*4; /* Name+Position+Chunk+ChunkStart+BlockStart */
-						loopsamples = info->loopofs + le32(p); sz -= 4; n -= 4;
-					}
-				}
-			}else if(memcmp(p-8, "data", 4) == 0 && info->dataofs == 0){
-				info->samples = n / info->width;
-				info->dataofs = p - in;
-			}else if(memcmp(p-8, "LIST", 4) == 0 && info->loopofs >= 0 && loopsamples == 0){
-				p += 4; sz -= 4; n -= 4; /* skip "adtl" */
-				if(n >= 20 && memcmp(p, "ltxt", 4) == 0 && memcmp(p+16, "mark", 4) == 0){
-					p += 12; sz -= 12; n -= 12;
 					loopsamples = info->loopofs + le32(p); sz -= 4; n -= 4;
 				}
 			}
+		}else if(memcmp(p-8, "data", 4) == 0 && info->dataofs == 0){
+			info->samples = n / info->width;
+			info->dataofs = p - in;
+		}else if(memcmp(p-8, "LIST", 4) == 0 && info->loopofs >= 0 && loopsamples == 0){
+			p += 4; sz -= 4; n -= 4; /* skip "adtl" */
+			if(n >= 20 && memcmp(p, "ltxt", 4) == 0 && memcmp(p+16, "mark", 4) == 0){
+				p += 12; sz -= 12; n -= 12;
+				loopsamples = info->loopofs + le32(p); sz -= 4; n -= 4;
+			}
 		}
+skip:
 		n = (n + 1) & ~1;
 		p += n; sz -= n;
 	}
 
+	if(info->width < 1 || info->channels < 1 || info->rate < 1){
+		werrstr("invalid/missing fmt chunk?");
+		return -1;
+	}
 	if(loopsamples > info->samples || info->loopofs > info->samples){
 		werrstr("invalid loop: (%d,%d) > %d", info->loopofs, loopsamples, info->samples);
 		return -1;