summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
71bcf40)
valgrind complains because of invalid reads/writes in vss.c:
==998== Invalid write of size 1
==998== at 0x8050B09: vss_post_select (vss.c:574)
==998== by 0x806106C: schedule (sched.c:71)
==998== by 0x804EE04: main (server.c:579)
==998== Address 0x46d99bc is 0 bytes after a block of size 548 alloc'd
==998== at 0x4028A3B: realloc (vg_replace_malloc.c:632)
==998== by 0x805356B: para_realloc (string.c:40)
==998== by 0x80506EC: vss_post_select (vss.c:331)
==998== by 0x806106C: schedule (sched.c:71)
==998== by 0x804EE04: main (server.c:579)
==998==
...
==5543== Invalid read of size 1
==5543== at 0x8050EBD: vss_post_select (vss.c:1099)
==5543== by 0x806108E: schedule (sched.c:71)
==5543== by 0x804EE04: main (server.c:579)
==5543== Address 0x47c70ac is 0 bytes after a block of size 3,956 alloc'd
==5543== at 0x4028A3B: realloc (vg_replace_malloc.c:632)
==5543== by 0x805358D: para_realloc (string.c:40)
==5543== by 0x80642AA: add_ogg_page (ogg_afh.c:78)
==5543== by 0x8064458: vorbis_get_header_callback (ogg_afh.c:132)
==5543== by 0x8063EF1: process_ogg_packets (ogg_afh_common.c:48)
==5543== by 0x8063F9A: ogg_get_file_info (ogg_afh_common.c:144)
==5543== by 0x8064200: vorbis_get_header (ogg_afh.c:149)
==5543== by 0x804FDD9: recv_afs_result (vss.c:1006)
==5543== by 0x80503F4: vss_post_select (vss.c:1124)
==5543== by 0x806108E: schedule (sched.c:71)
==5543== by 0x804EE04: main (server.c:579)
The problem is that for ogg streams chunk 0 points to a buffer on
the heap rather than to the mapped audio file, but we are checking
the buffer bounds against the memory map.
The fix consists of two parts. (a) We now treat a FEC group special
if it starts at chunk zero: Such a group now contains only this single
chunk. (b) When setting up the FEC group we always compare the buffer
bounds against the start of the first buffer in the group rather than
the memory map.
static void compute_group_size(struct vss_task *vsst, struct fec_group *g,
int max_bytes)
{
static void compute_group_size(struct vss_task *vsst, struct fec_group *g,
int max_bytes)
{
+ char *buf;
+ size_t len;
int i, max_chunks = PARA_MAX(1LU, 150 / tv2ms(vss_chunk_time()));
int i, max_chunks = PARA_MAX(1LU, 150 / tv2ms(vss_chunk_time()));
+ if (g->first_chunk == 0) {
+ g->num_chunks = 1;
+ vss_get_chunk(0, vsst, &buf, &len);
+ g->bytes = len;
+ return;
+ }
+
g->num_chunks = 0;
g->bytes = 0;
/*
g->num_chunks = 0;
g->bytes = 0;
/*
* of exactly one chunk for these audio formats.
*/
for (i = 0;; i++) {
* of exactly one chunk for these audio formats.
*/
for (i = 0;; i++) {
- char *buf;
- size_t len;
int chunk_num = g->first_chunk + i;
if (g->bytes > 0 && i >= max_chunks) /* duration limit */
int chunk_num = g->first_chunk + i;
if (g->bytes > 0 && i >= max_chunks) /* duration limit */
{
int ret, i, k, n, data_slices;
size_t len;
{
int ret, i, k, n, data_slices;
size_t len;
struct fec_group *g = &fc->group;
if (fc->state == FEC_STATE_NONE) {
struct fec_group *g = &fc->group;
if (fc->state == FEC_STATE_NONE) {
assert(i == g->num_header_slices - 1);
}
assert(i == g->num_header_slices - 1);
}
- /* setup data slices */
+ /*
+ * Setup data slices. Note that for ogg streams chunk 0 points to a
+ * buffer on the heap rather than to the mapped audio file.
+ */
vss_get_chunk(g->first_chunk, vsst, &buf, &len);
vss_get_chunk(g->first_chunk, vsst, &buf, &len);
- for (; i < g->num_header_slices + data_slices; i++) {
- if (buf + g->slice_bytes > vsst->map + mmd->size) {
+ for (p = buf; i < g->num_header_slices + data_slices; i++) {
+ if (p + g->slice_bytes > buf + g->bytes) {
- * Can not use the memory mapped audio file for this
- * slice as it goes beyond the map.
+ * We must make a copy for this slice since using p
+ * directly would exceed the buffer.
- uint32_t payload_size = vsst->map + mmd->size - buf;
- memcpy(fc->extra_src_buf, buf, payload_size);
+ uint32_t payload_size = buf + g->bytes - p;
+ assert(payload_size + FEC_HEADER_SIZE <= fc->mps);
+ memcpy(fc->extra_src_buf, p, payload_size);
if (payload_size < g->slice_bytes)
memset(fc->extra_src_buf + payload_size, 0,
g->slice_bytes - payload_size);
if (payload_size < g->slice_bytes)
memset(fc->extra_src_buf + payload_size, 0,
g->slice_bytes - payload_size);
- fc->src_data[i] = (const unsigned char *)buf;
- buf += g->slice_bytes;
+ fc->src_data[i] = (const unsigned char *)p;
+ p += g->slice_bytes;
}
if (i < k) {
/* use arbitrary data for all remaining slices */
}
if (i < k) {
/* use arbitrary data for all remaining slices */