diff options
Diffstat (limited to 'meta/recipes-multimedia/libsndfile/libsndfile1/CVE-2024-50612.patch')
-rw-r--r-- | meta/recipes-multimedia/libsndfile/libsndfile1/CVE-2024-50612.patch | 409 |
1 files changed, 409 insertions, 0 deletions
diff --git a/meta/recipes-multimedia/libsndfile/libsndfile1/CVE-2024-50612.patch b/meta/recipes-multimedia/libsndfile/libsndfile1/CVE-2024-50612.patch new file mode 100644 index 0000000000..368dd5446b --- /dev/null +++ b/meta/recipes-multimedia/libsndfile/libsndfile1/CVE-2024-50612.patch | |||
@@ -0,0 +1,409 @@ | |||
1 | From 4755f5bd7854611d92ad0f1295587b439f9950ba Mon Sep 17 00:00:00 2001 | ||
2 | From: Arthur Taylor <art@ified.ca> | ||
3 | Date: Fri, 15 Nov 2024 19:46:53 -0800 | ||
4 | Subject: [PATCH] src/ogg: better error checking for vorbis. Fixes #1035 | ||
5 | |||
6 | CVE: CVE-2024-50612 | ||
7 | Upstream-Status: Backport [4755f5bd7854611d92ad0f1295587b439f9950ba] | ||
8 | Signed-off-by: Ross Burton <ross.burton@arm.com> | ||
9 | --- | ||
10 | src/ogg.c | 12 ++-- | ||
11 | src/ogg_opus.c | 17 +++-- | ||
12 | src/ogg_vorbis.c | 170 ++++++++++++++++++++++++++--------------------- | ||
13 | 3 files changed, 114 insertions(+), 85 deletions(-) | ||
14 | |||
15 | diff --git a/src/ogg.c b/src/ogg.c | ||
16 | index 529941af8..e2d679d41 100644 | ||
17 | --- a/src/ogg.c | ||
18 | +++ b/src/ogg.c | ||
19 | @@ -211,12 +211,16 @@ ogg_read_first_page (SF_PRIVATE *psf, OGG_PRIVATE *odata) | ||
20 | |||
21 | int | ||
22 | ogg_write_page (SF_PRIVATE *psf, ogg_page *page) | ||
23 | -{ int bytes ; | ||
24 | +{ int n ; | ||
25 | |||
26 | - bytes = psf_fwrite (page->header, 1, page->header_len, psf) ; | ||
27 | - bytes += psf_fwrite (page->body, 1, page->body_len, psf) ; | ||
28 | + n = psf_fwrite (page->header, 1, page->header_len, psf) ; | ||
29 | + if (n == page->header_len) | ||
30 | + n += psf_fwrite (page->body, 1, page->body_len, psf) ; | ||
31 | |||
32 | - return bytes == page->header_len + page->body_len ; | ||
33 | + if (n != page->body_len + page->header_len) | ||
34 | + return -1 ; | ||
35 | + | ||
36 | + return n ; | ||
37 | } /* ogg_write_page */ | ||
38 | |||
39 | sf_count_t | ||
40 | diff --git a/src/ogg_opus.c b/src/ogg_opus.c | ||
41 | index 511653ecc..e01224b99 100644 | ||
42 | --- a/src/ogg_opus.c | ||
43 | +++ b/src/ogg_opus.c | ||
44 | @@ -827,15 +827,16 @@ ogg_opus_write_header (SF_PRIVATE *psf, int UNUSED (calc_length)) | ||
45 | |||
46 | /* The first page MUST only contain the header, so flush it out now */ | ||
47 | ogg_stream_packetin (&odata->ostream, &op) ; | ||
48 | - for ( ; (nn = ogg_stream_flush (&odata->ostream, &odata->opage)) ; ) | ||
49 | - { if (! (nn = ogg_write_page (psf, &odata->opage))) | ||
50 | + while (ogg_stream_flush (&odata->ostream, &odata->opage)) | ||
51 | + { nn = ogg_write_page (psf, &odata->opage) ; | ||
52 | + if (nn < 0) | ||
53 | { psf_log_printf (psf, "Opus : Failed to write header!\n") ; | ||
54 | if (psf->error) | ||
55 | return psf->error ; | ||
56 | return SFE_INTERNAL ; | ||
57 | } ; | ||
58 | psf->dataoffset += nn ; | ||
59 | - } | ||
60 | + } ; | ||
61 | |||
62 | /* | ||
63 | ** Metadata Tags (manditory) | ||
64 | @@ -850,15 +851,16 @@ ogg_opus_write_header (SF_PRIVATE *psf, int UNUSED (calc_length)) | ||
65 | vorbiscomment_write_tags (psf, &op, &opustags_ident, opus_get_version_string (), - (OGG_OPUS_COMMENT_PAD)) ; | ||
66 | op.packetno = 2 ; | ||
67 | ogg_stream_packetin (&odata->ostream, &op) ; | ||
68 | - for ( ; (nn = ogg_stream_flush (&odata->ostream, &odata->opage)) ; ) | ||
69 | - { if (! (nn = ogg_write_page (psf, &odata->opage))) | ||
70 | + while (ogg_stream_flush (&odata->ostream, &odata->opage)) | ||
71 | + { nn = ogg_write_page (psf, &odata->opage) ; | ||
72 | + if (nn < 0) | ||
73 | { psf_log_printf (psf, "Opus : Failed to write comments!\n") ; | ||
74 | if (psf->error) | ||
75 | return psf->error ; | ||
76 | return SFE_INTERNAL ; | ||
77 | } ; | ||
78 | psf->dataoffset += nn ; | ||
79 | - } | ||
80 | + } ; | ||
81 | |||
82 | return 0 ; | ||
83 | } /* ogg_opus_write_header */ | ||
84 | @@ -1132,7 +1134,8 @@ ogg_opus_write_out (SF_PRIVATE *psf, OGG_PRIVATE *odata, OPUS_PRIVATE *oopus) | ||
85 | if (nbytes > 0) | ||
86 | { oopus->u.encode.last_segments -= ogg_page_segments (&odata->opage) ; | ||
87 | oopus->pg_pos = oopus->pkt_pos ; | ||
88 | - ogg_write_page (psf, &odata->opage) ; | ||
89 | + if (ogg_write_page (psf, &odata->opage) < 0) | ||
90 | + return -1 ; | ||
91 | } | ||
92 | else | ||
93 | break ; | ||
94 | diff --git a/src/ogg_vorbis.c b/src/ogg_vorbis.c | ||
95 | index add123966..fae252ca0 100644 | ||
96 | --- a/src/ogg_vorbis.c | ||
97 | +++ b/src/ogg_vorbis.c | ||
98 | @@ -82,28 +82,6 @@ | ||
99 | /* How many seconds in the future to not bother bisection searching for. */ | ||
100 | #define VORBIS_SEEK_THRESHOLD 2 | ||
101 | |||
102 | -typedef int convert_func (SF_PRIVATE *psf, int, void *, int, int, float **) ; | ||
103 | - | ||
104 | -static int vorbis_read_header (SF_PRIVATE *psf) ; | ||
105 | -static int vorbis_write_header (SF_PRIVATE *psf, int calc_length) ; | ||
106 | -static int vorbis_close (SF_PRIVATE *psf) ; | ||
107 | -static int vorbis_command (SF_PRIVATE *psf, int command, void *data, int datasize) ; | ||
108 | -static int vorbis_byterate (SF_PRIVATE *psf) ; | ||
109 | -static int vorbis_calculate_granulepos (SF_PRIVATE *psf, uint64_t *gp_out) ; | ||
110 | -static int vorbis_skip (SF_PRIVATE *psf, uint64_t target_gp) ; | ||
111 | -static int vorbis_seek_trysearch (SF_PRIVATE *psf, uint64_t target_gp) ; | ||
112 | -static sf_count_t vorbis_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ; | ||
113 | -static sf_count_t vorbis_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ; | ||
114 | -static sf_count_t vorbis_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ; | ||
115 | -static sf_count_t vorbis_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ; | ||
116 | -static sf_count_t vorbis_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ; | ||
117 | -static sf_count_t vorbis_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ; | ||
118 | -static sf_count_t vorbis_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ; | ||
119 | -static sf_count_t vorbis_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ; | ||
120 | -static sf_count_t vorbis_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ; | ||
121 | -static sf_count_t vorbis_read_sample (SF_PRIVATE *psf, void *ptr, sf_count_t lens, convert_func *transfn) ; | ||
122 | -static int vorbis_rnull (SF_PRIVATE *psf, int samples, void *vptr, int off , int channels, float **pcm) ; | ||
123 | - | ||
124 | typedef struct | ||
125 | { int id ; | ||
126 | const char *name ; | ||
127 | @@ -145,6 +123,45 @@ typedef struct | ||
128 | sf_count_t last_page ; | ||
129 | } VORBIS_PRIVATE ; | ||
130 | |||
131 | +typedef int convert_func (SF_PRIVATE *psf, int, void *, int, int, float **) ; | ||
132 | + | ||
133 | +static int vorbis_read_header (SF_PRIVATE *psf) ; | ||
134 | +static int vorbis_write_header (SF_PRIVATE *psf, int calc_length) ; | ||
135 | +static int vorbis_close (SF_PRIVATE *psf) ; | ||
136 | +static int vorbis_command (SF_PRIVATE *psf, int command, void *data, int datasize) ; | ||
137 | +static int vorbis_byterate (SF_PRIVATE *psf) ; | ||
138 | +static int vorbis_calculate_granulepos (SF_PRIVATE *psf, uint64_t *gp_out) ; | ||
139 | +static int vorbis_skip (SF_PRIVATE *psf, uint64_t target_gp) ; | ||
140 | +static int vorbis_seek_trysearch (SF_PRIVATE *psf, uint64_t target_gp) ; | ||
141 | +static sf_count_t vorbis_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ; | ||
142 | +static sf_count_t vorbis_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ; | ||
143 | +static sf_count_t vorbis_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ; | ||
144 | +static sf_count_t vorbis_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ; | ||
145 | +static sf_count_t vorbis_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ; | ||
146 | +static sf_count_t vorbis_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ; | ||
147 | +static sf_count_t vorbis_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ; | ||
148 | +static sf_count_t vorbis_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ; | ||
149 | +static sf_count_t vorbis_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ; | ||
150 | +static sf_count_t vorbis_read_sample (SF_PRIVATE *psf, void *ptr, sf_count_t lens, convert_func *transfn) ; | ||
151 | +static int vorbis_write_samples (SF_PRIVATE *psf, OGG_PRIVATE *odata, VORBIS_PRIVATE *vdata, int in_frames) ; | ||
152 | +static int vorbis_rnull (SF_PRIVATE *psf, int samples, void *vptr, int off , int channels, float **pcm) ; | ||
153 | +static void vorbis_log_error (SF_PRIVATE *psf, int error) ; | ||
154 | + | ||
155 | + | ||
156 | +static void | ||
157 | +vorbis_log_error(SF_PRIVATE *psf, int error) { | ||
158 | + switch (error) | ||
159 | + { case 0: return; | ||
160 | + case OV_EIMPL: psf->error = SFE_UNIMPLEMENTED ; break ; | ||
161 | + case OV_ENOTVORBIS: psf->error = SFE_MALFORMED_FILE ; break ; | ||
162 | + case OV_EBADHEADER: psf->error = SFE_MALFORMED_FILE ; break ; | ||
163 | + case OV_EVERSION: psf->error = SFE_UNSUPPORTED_ENCODING ; break ; | ||
164 | + case OV_EFAULT: | ||
165 | + case OV_EINVAL: | ||
166 | + default: psf->error = SFE_INTERNAL ; | ||
167 | + } ; | ||
168 | +} ; | ||
169 | + | ||
170 | static int | ||
171 | vorbis_read_header (SF_PRIVATE *psf) | ||
172 | { OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ; | ||
173 | @@ -380,7 +397,6 @@ vorbis_write_header (SF_PRIVATE *psf, int UNUSED (calc_length)) | ||
174 | { ogg_packet header ; | ||
175 | ogg_packet header_comm ; | ||
176 | ogg_packet header_code ; | ||
177 | - int result ; | ||
178 | |||
179 | vorbis_analysis_headerout (&vdata->vdsp, &vdata->vcomment, &header, &header_comm, &header_code) ; | ||
180 | ogg_stream_packetin (&odata->ostream, &header) ; /* automatically placed in its own page */ | ||
181 | @@ -390,9 +406,9 @@ vorbis_write_header (SF_PRIVATE *psf, int UNUSED (calc_length)) | ||
182 | /* This ensures the actual | ||
183 | * audio data will start on a new page, as per spec | ||
184 | */ | ||
185 | - while ((result = ogg_stream_flush (&odata->ostream, &odata->opage)) != 0) | ||
186 | - { ogg_write_page (psf, &odata->opage) ; | ||
187 | - } ; | ||
188 | + while (ogg_stream_flush (&odata->ostream, &odata->opage)) | ||
189 | + if (ogg_write_page (psf, &odata->opage) < 0) | ||
190 | + return -1 ; | ||
191 | } | ||
192 | |||
193 | return 0 ; | ||
194 | @@ -402,6 +418,7 @@ static int | ||
195 | vorbis_close (SF_PRIVATE *psf) | ||
196 | { OGG_PRIVATE* odata = psf->container_data ; | ||
197 | VORBIS_PRIVATE *vdata = psf->codec_data ; | ||
198 | + int ret = 0 ; | ||
199 | |||
200 | if (odata == NULL || vdata == NULL) | ||
201 | return 0 ; | ||
202 | @@ -412,34 +429,14 @@ vorbis_close (SF_PRIVATE *psf) | ||
203 | if (psf->file.mode == SFM_WRITE) | ||
204 | { | ||
205 | if (psf->write_current <= 0) | ||
206 | - vorbis_write_header (psf, 0) ; | ||
207 | - | ||
208 | - vorbis_analysis_wrote (&vdata->vdsp, 0) ; | ||
209 | - while (vorbis_analysis_blockout (&vdata->vdsp, &vdata->vblock) == 1) | ||
210 | - { | ||
211 | + ret = vorbis_write_header (psf, 0) ; | ||
212 | |||
213 | - /* analysis, assume we want to use bitrate management */ | ||
214 | - vorbis_analysis (&vdata->vblock, NULL) ; | ||
215 | - vorbis_bitrate_addblock (&vdata->vblock) ; | ||
216 | - | ||
217 | - while (vorbis_bitrate_flushpacket (&vdata->vdsp, &odata->opacket)) | ||
218 | - { /* weld the packet into the bitstream */ | ||
219 | - ogg_stream_packetin (&odata->ostream, &odata->opacket) ; | ||
220 | - | ||
221 | - /* write out pages (if any) */ | ||
222 | - while (!odata->eos) | ||
223 | - { int result = ogg_stream_pageout (&odata->ostream, &odata->opage) ; | ||
224 | - if (result == 0) break ; | ||
225 | - ogg_write_page (psf, &odata->opage) ; | ||
226 | - | ||
227 | - /* this could be set above, but for illustrative purposes, I do | ||
228 | - it here (to show that vorbis does know where the stream ends) */ | ||
229 | - | ||
230 | - if (ogg_page_eos (&odata->opage)) odata->eos = 1 ; | ||
231 | - } | ||
232 | - } | ||
233 | - } | ||
234 | - } | ||
235 | + if (ret == 0) | ||
236 | + { /* A write of zero samples tells Vorbis the stream is done and to | ||
237 | + flush. */ | ||
238 | + ret = vorbis_write_samples (psf, odata, vdata, 0) ; | ||
239 | + } ; | ||
240 | + } ; | ||
241 | |||
242 | /* ogg_page and ogg_packet structs always point to storage in | ||
243 | libvorbis. They are never freed or manipulated directly */ | ||
244 | @@ -449,7 +446,7 @@ vorbis_close (SF_PRIVATE *psf) | ||
245 | vorbis_comment_clear (&vdata->vcomment) ; | ||
246 | vorbis_info_clear (&vdata->vinfo) ; | ||
247 | |||
248 | - return 0 ; | ||
249 | + return ret ; | ||
250 | } /* vorbis_close */ | ||
251 | |||
252 | int | ||
253 | @@ -688,33 +685,40 @@ vorbis_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t lens) | ||
254 | /*============================================================================== | ||
255 | */ | ||
256 | |||
257 | -static void | ||
258 | +static int | ||
259 | vorbis_write_samples (SF_PRIVATE *psf, OGG_PRIVATE *odata, VORBIS_PRIVATE *vdata, int in_frames) | ||
260 | -{ | ||
261 | - vorbis_analysis_wrote (&vdata->vdsp, in_frames) ; | ||
262 | +{ int ret ; | ||
263 | + | ||
264 | + if ((ret = vorbis_analysis_wrote (&vdata->vdsp, in_frames)) != 0) | ||
265 | + return ret ; | ||
266 | |||
267 | /* | ||
268 | ** Vorbis does some data preanalysis, then divvies up blocks for | ||
269 | ** more involved (potentially parallel) processing. Get a single | ||
270 | ** block for encoding now. | ||
271 | */ | ||
272 | - while (vorbis_analysis_blockout (&vdata->vdsp, &vdata->vblock) == 1) | ||
273 | + while ((ret = vorbis_analysis_blockout (&vdata->vdsp, &vdata->vblock)) == 1) | ||
274 | { | ||
275 | /* analysis, assume we want to use bitrate management */ | ||
276 | - vorbis_analysis (&vdata->vblock, NULL) ; | ||
277 | - vorbis_bitrate_addblock (&vdata->vblock) ; | ||
278 | + if ((ret = vorbis_analysis (&vdata->vblock, NULL)) != 0) | ||
279 | + return ret ; | ||
280 | + if ((ret = vorbis_bitrate_addblock (&vdata->vblock)) != 0) | ||
281 | + return ret ; | ||
282 | |||
283 | - while (vorbis_bitrate_flushpacket (&vdata->vdsp, &odata->opacket)) | ||
284 | + while ((ret = vorbis_bitrate_flushpacket (&vdata->vdsp, &odata->opacket)) == 1) | ||
285 | { | ||
286 | /* weld the packet into the bitstream */ | ||
287 | - ogg_stream_packetin (&odata->ostream, &odata->opacket) ; | ||
288 | + if ((ret = ogg_stream_packetin (&odata->ostream, &odata->opacket)) != 0) | ||
289 | + return ret ; | ||
290 | |||
291 | /* write out pages (if any) */ | ||
292 | while (!odata->eos) | ||
293 | - { int result = ogg_stream_pageout (&odata->ostream, &odata->opage) ; | ||
294 | - if (result == 0) | ||
295 | + { ret = ogg_stream_pageout (&odata->ostream, &odata->opage) ; | ||
296 | + if (ret == 0) | ||
297 | break ; | ||
298 | - ogg_write_page (psf, &odata->opage) ; | ||
299 | + | ||
300 | + if (ogg_write_page (psf, &odata->opage) < 0) | ||
301 | + return -1 ; | ||
302 | |||
303 | /* This could be set above, but for illustrative purposes, I do | ||
304 | ** it here (to show that vorbis does know where the stream ends) */ | ||
305 | @@ -722,16 +726,22 @@ vorbis_write_samples (SF_PRIVATE *psf, OGG_PRIVATE *odata, VORBIS_PRIVATE *vdata | ||
306 | odata->eos = 1 ; | ||
307 | } ; | ||
308 | } ; | ||
309 | + if (ret != 0) | ||
310 | + return ret ; | ||
311 | } ; | ||
312 | + if (ret != 0) | ||
313 | + return ret ; | ||
314 | |||
315 | vdata->gp += in_frames ; | ||
316 | + | ||
317 | + return 0 ; | ||
318 | } /* vorbis_write_data */ | ||
319 | |||
320 | |||
321 | static sf_count_t | ||
322 | vorbis_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t lens) | ||
323 | { | ||
324 | - int i, m, j = 0 ; | ||
325 | + int i, m, j = 0, ret ; | ||
326 | OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ; | ||
327 | VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ; | ||
328 | int in_frames = lens / psf->sf.channels ; | ||
329 | @@ -740,14 +750,17 @@ vorbis_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t lens) | ||
330 | for (m = 0 ; m < psf->sf.channels ; m++) | ||
331 | buffer [m][i] = (float) (ptr [j++]) / 32767.0f ; | ||
332 | |||
333 | - vorbis_write_samples (psf, odata, vdata, in_frames) ; | ||
334 | + if ((ret = vorbis_write_samples (psf, odata, vdata, in_frames))) | ||
335 | + { vorbis_log_error (psf, ret) ; | ||
336 | + return 0 ; | ||
337 | + } ; | ||
338 | |||
339 | return lens ; | ||
340 | } /* vorbis_write_s */ | ||
341 | |||
342 | static sf_count_t | ||
343 | vorbis_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t lens) | ||
344 | -{ int i, m, j = 0 ; | ||
345 | +{ int i, m, j = 0, ret ; | ||
346 | OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ; | ||
347 | VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ; | ||
348 | int in_frames = lens / psf->sf.channels ; | ||
349 | @@ -756,14 +769,17 @@ vorbis_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t lens) | ||
350 | for (m = 0 ; m < psf->sf.channels ; m++) | ||
351 | buffer [m][i] = (float) (ptr [j++]) / 2147483647.0f ; | ||
352 | |||
353 | - vorbis_write_samples (psf, odata, vdata, in_frames) ; | ||
354 | + if ((ret = vorbis_write_samples (psf, odata, vdata, in_frames))) | ||
355 | + { vorbis_log_error (psf, ret) ; | ||
356 | + return 0 ; | ||
357 | + } ; | ||
358 | |||
359 | return lens ; | ||
360 | } /* vorbis_write_i */ | ||
361 | |||
362 | static sf_count_t | ||
363 | vorbis_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t lens) | ||
364 | -{ int i, m, j = 0 ; | ||
365 | +{ int i, m, j = 0, ret ; | ||
366 | OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ; | ||
367 | VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ; | ||
368 | int in_frames = lens / psf->sf.channels ; | ||
369 | @@ -772,14 +788,17 @@ vorbis_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t lens) | ||
370 | for (m = 0 ; m < psf->sf.channels ; m++) | ||
371 | buffer [m][i] = ptr [j++] ; | ||
372 | |||
373 | - vorbis_write_samples (psf, odata, vdata, in_frames) ; | ||
374 | + if ((ret = vorbis_write_samples (psf, odata, vdata, in_frames)) != 0) | ||
375 | + { vorbis_log_error (psf, ret) ; | ||
376 | + return 0 ; | ||
377 | + } ; | ||
378 | |||
379 | return lens ; | ||
380 | } /* vorbis_write_f */ | ||
381 | |||
382 | static sf_count_t | ||
383 | vorbis_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t lens) | ||
384 | -{ int i, m, j = 0 ; | ||
385 | +{ int i, m, j = 0, ret ; | ||
386 | OGG_PRIVATE *odata = (OGG_PRIVATE *) psf->container_data ; | ||
387 | VORBIS_PRIVATE *vdata = (VORBIS_PRIVATE *) psf->codec_data ; | ||
388 | int in_frames = lens / psf->sf.channels ; | ||
389 | @@ -788,7 +807,10 @@ vorbis_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t lens) | ||
390 | for (m = 0 ; m < psf->sf.channels ; m++) | ||
391 | buffer [m][i] = (float) ptr [j++] ; | ||
392 | |||
393 | - vorbis_write_samples (psf, odata, vdata, in_frames) ; | ||
394 | + if ((ret = vorbis_write_samples (psf, odata, vdata, in_frames)) != 0) | ||
395 | + { vorbis_log_error (psf, ret) ; | ||
396 | + return 0 ; | ||
397 | + } ; | ||
398 | |||
399 | return lens ; | ||
400 | } /* vorbis_write_d */ | ||
401 | @@ -884,7 +906,7 @@ vorbis_seek_trysearch (SF_PRIVATE *psf, uint64_t target_gp) | ||
402 | return 0 ; | ||
403 | |||
404 | /* Search for a position a half large-block before our target. As Vorbis is | ||
405 | - ** lapped, every sample position come from two blocks, the "left" half of | ||
406 | + ** lapped, every sample position comes from two blocks, the "left" half of | ||
407 | ** one block and the "right" half of the previous block. The granule | ||
408 | ** position of an Ogg page of a Vorbis stream is the sample offset of the | ||
409 | ** last finished sample in the stream that can be decoded from a page. A | ||