|
Line 0
Link Here
|
|
|
1 |
From d5bf76b5a88d044a1be1d5656698e3ba737167e5 Mon Sep 17 00:00:00 2001 |
| 2 |
From: David Bryant <david@wavpack.com> |
| 3 |
Date: Sun, 4 Feb 2018 11:28:15 -0800 |
| 4 |
Subject: [PATCH 1/6] issue #27, do not overwrite stack on corrupt RF64 file |
| 5 |
|
| 6 |
--- |
| 7 |
cli/riff.c | 39 ++++++++++++++++++++++++++++++++------- |
| 8 |
1 file changed, 32 insertions(+), 7 deletions(-) |
| 9 |
|
| 10 |
diff --git cli/riff.c cli/riff.c |
| 11 |
index 8b1af45..de98c1e 100644 |
| 12 |
--- cli/riff.c |
| 13 |
+++ cli/riff.c |
| 14 |
@@ -42,6 +42,7 @@ typedef struct { |
| 15 |
|
| 16 |
#pragma pack(pop) |
| 17 |
|
| 18 |
+#define CS64ChunkFormat "4D" |
| 19 |
#define DS64ChunkFormat "DDDL" |
| 20 |
|
| 21 |
#define WAVPACK_NO_ERROR 0 |
| 22 |
@@ -101,13 +102,13 @@ int ParseRiffHeaderConfig (FILE *infile, char *infilename, char *fourcc, Wavpack |
| 23 |
|
| 24 |
if (!strncmp (chunk_header.ckID, "ds64", 4)) { |
| 25 |
if (chunk_header.ckSize < sizeof (DS64Chunk) || |
| 26 |
- !DoReadFile (infile, &ds64_chunk, chunk_header.ckSize, &bcount) || |
| 27 |
- bcount != chunk_header.ckSize) { |
| 28 |
+ !DoReadFile (infile, &ds64_chunk, sizeof (DS64Chunk), &bcount) || |
| 29 |
+ bcount != sizeof (DS64Chunk)) { |
| 30 |
error_line ("%s is not a valid .WAV file!", infilename); |
| 31 |
return WAVPACK_SOFT_ERROR; |
| 32 |
} |
| 33 |
else if (!(config->qmode & QMODE_NO_STORE_WRAPPER) && |
| 34 |
- !WavpackAddWrapper (wpc, &ds64_chunk, chunk_header.ckSize)) { |
| 35 |
+ !WavpackAddWrapper (wpc, &ds64_chunk, sizeof (DS64Chunk))) { |
| 36 |
error_line ("%s", WavpackGetErrorMessage (wpc)); |
| 37 |
return WAVPACK_SOFT_ERROR; |
| 38 |
} |
| 39 |
@@ -315,10 +316,11 @@ int ParseRiffHeaderConfig (FILE *infile, char *infilename, char *fourcc, Wavpack |
| 40 |
|
| 41 |
int WriteRiffHeader (FILE *outfile, WavpackContext *wpc, int64_t total_samples, int qmode) |
| 42 |
{ |
| 43 |
- int do_rf64 = 0, write_junk = 1; |
| 44 |
+ int do_rf64 = 0, write_junk = 1, table_length = 0; |
| 45 |
ChunkHeader ds64hdr, datahdr, fmthdr; |
| 46 |
RiffChunkHeader riffhdr; |
| 47 |
DS64Chunk ds64_chunk; |
| 48 |
+ CS64Chunk cs64_chunk; |
| 49 |
JunkChunk junkchunk; |
| 50 |
WaveHeader wavhdr; |
| 51 |
uint32_t bcount; |
| 52 |
@@ -380,6 +382,7 @@ int WriteRiffHeader (FILE *outfile, WavpackContext *wpc, int64_t total_samples, |
| 53 |
strncpy (riffhdr.formType, "WAVE", sizeof (riffhdr.formType)); |
| 54 |
total_riff_bytes = sizeof (riffhdr) + wavhdrsize + sizeof (datahdr) + ((total_data_bytes + 1) & ~(int64_t)1); |
| 55 |
if (do_rf64) total_riff_bytes += sizeof (ds64hdr) + sizeof (ds64_chunk); |
| 56 |
+ total_riff_bytes += table_length * sizeof (CS64Chunk); |
| 57 |
if (write_junk) total_riff_bytes += sizeof (junkchunk); |
| 58 |
strncpy (fmthdr.ckID, "fmt ", sizeof (fmthdr.ckID)); |
| 59 |
strncpy (datahdr.ckID, "data", sizeof (datahdr.ckID)); |
| 60 |
@@ -394,11 +397,12 @@ int WriteRiffHeader (FILE *outfile, WavpackContext *wpc, int64_t total_samples, |
| 61 |
|
| 62 |
if (do_rf64) { |
| 63 |
strncpy (ds64hdr.ckID, "ds64", sizeof (ds64hdr.ckID)); |
| 64 |
- ds64hdr.ckSize = sizeof (ds64_chunk); |
| 65 |
+ ds64hdr.ckSize = sizeof (ds64_chunk) + (table_length * sizeof (CS64Chunk)); |
| 66 |
CLEAR (ds64_chunk); |
| 67 |
ds64_chunk.riffSize64 = total_riff_bytes; |
| 68 |
ds64_chunk.dataSize64 = total_data_bytes; |
| 69 |
ds64_chunk.sampleCount64 = total_samples; |
| 70 |
+ ds64_chunk.tableLength = table_length; |
| 71 |
riffhdr.ckSize = (uint32_t) -1; |
| 72 |
datahdr.ckSize = (uint32_t) -1; |
| 73 |
WavpackNativeToLittleEndian (&ds64hdr, ChunkHeaderFormat); |
| 74 |
@@ -409,6 +413,14 @@ int WriteRiffHeader (FILE *outfile, WavpackContext *wpc, int64_t total_samples, |
| 75 |
datahdr.ckSize = (uint32_t) total_data_bytes; |
| 76 |
} |
| 77 |
|
| 78 |
+ // this "table" is just a dummy placeholder for testing (normally not written) |
| 79 |
+ |
| 80 |
+ if (table_length) { |
| 81 |
+ strncpy (cs64_chunk.ckID, "dmmy", sizeof (cs64_chunk.ckID)); |
| 82 |
+ cs64_chunk.chunkSize64 = 12345678; |
| 83 |
+ WavpackNativeToLittleEndian (&cs64_chunk, CS64ChunkFormat); |
| 84 |
+ } |
| 85 |
+ |
| 86 |
// write the RIFF chunks up to just before the data starts |
| 87 |
|
| 88 |
WavpackNativeToLittleEndian (&riffhdr, ChunkHeaderFormat); |
| 89 |
@@ -418,8 +430,21 @@ int WriteRiffHeader (FILE *outfile, WavpackContext *wpc, int64_t total_samples, |
| 90 |
|
| 91 |
if (!DoWriteFile (outfile, &riffhdr, sizeof (riffhdr), &bcount) || bcount != sizeof (riffhdr) || |
| 92 |
(do_rf64 && (!DoWriteFile (outfile, &ds64hdr, sizeof (ds64hdr), &bcount) || bcount != sizeof (ds64hdr))) || |
| 93 |
- (do_rf64 && (!DoWriteFile (outfile, &ds64_chunk, sizeof (ds64_chunk), &bcount) || bcount != sizeof (ds64_chunk))) || |
| 94 |
- (write_junk && (!DoWriteFile (outfile, &junkchunk, sizeof (junkchunk), &bcount) || bcount != sizeof (junkchunk))) || |
| 95 |
+ (do_rf64 && (!DoWriteFile (outfile, &ds64_chunk, sizeof (ds64_chunk), &bcount) || bcount != sizeof (ds64_chunk)))) { |
| 96 |
+ error_line ("can't write .WAV data, disk probably full!"); |
| 97 |
+ return FALSE; |
| 98 |
+ } |
| 99 |
+ |
| 100 |
+ // again, this is normally not written except for testing |
| 101 |
+ |
| 102 |
+ while (table_length--) |
| 103 |
+ if (!DoWriteFile (outfile, &cs64_chunk, sizeof (cs64_chunk), &bcount) || bcount != sizeof (cs64_chunk)) { |
| 104 |
+ error_line ("can't write .WAV data, disk probably full!"); |
| 105 |
+ return FALSE; |
| 106 |
+ } |
| 107 |
+ |
| 108 |
+ |
| 109 |
+ if ((write_junk && (!DoWriteFile (outfile, &junkchunk, sizeof (junkchunk), &bcount) || bcount != sizeof (junkchunk))) || |
| 110 |
!DoWriteFile (outfile, &fmthdr, sizeof (fmthdr), &bcount) || bcount != sizeof (fmthdr) || |
| 111 |
!DoWriteFile (outfile, &wavhdr, wavhdrsize, &bcount) || bcount != wavhdrsize || |
| 112 |
!DoWriteFile (outfile, &datahdr, sizeof (datahdr), &bcount) || bcount != sizeof (datahdr)) { |
| 113 |
-- |
| 114 |
2.17.0 |
| 115 |
|