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 |
|