* @author Peter Ross <pross@xvid.org>
*/
+#include <inttypes.h>
+
#include "libavutil/channel_layout.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/intfloat.h"
/* Macros for formating GUIDs */
#define PRI_PRETTY_GUID \
- "%08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x"
+ "%08"PRIx32"-%04"PRIx16"-%04"PRIx16"-%02x%02x%02x%02x%02x%02x%02x%02x"
#define ARG_PRETTY_GUID(g) \
AV_RL32(g),AV_RL16(g+4),AV_RL16(g+6),g[8],g[9],g[10],g[11],g[12],g[13],g[14],g[15]
#define LEN_PRETTY_GUID 34
*
*/
-#define WTV_SECTOR_BITS INT64_C(12)
+#define WTV_SECTOR_BITS 12
#define WTV_SECTOR_SIZE (1 << WTV_SECTOR_BITS)
#define WTV_BIGSECTOR_BITS 18
+#define SHIFT_SECTOR_BITS(a) ((int64_t)(a) << WTV_SECTOR_BITS)
+
typedef struct {
AVIOContext *pb_filesystem; /** file system (AVFormatContext->pb) */
int64_t length;
} WtvFile;
+static int64_t seek_by_sector(AVIOContext *pb, int64_t sector, int64_t offset)
+{
+ return avio_seek(pb, SHIFT_SECTOR_BITS(sector) + offset, SEEK_SET);
+}
+
/**
* @return bytes read, 0 on end of file, or <0 on error
*/
int i = wf->position >> wf->sector_bits;
if (i >= wf->nb_sectors ||
(wf->sectors[i] != wf->sectors[i - 1] + (1 << (wf->sector_bits - WTV_SECTOR_BITS)) &&
- avio_seek(pb, (int64_t)wf->sectors[i] << WTV_SECTOR_BITS, SEEK_SET) < 0)) {
+ seek_by_sector(pb, wf->sectors[i], 0) < 0)) {
wf->error = 1;
break;
}
offset = wf->length;
wf->error = offset < 0 || offset >= wf->length ||
- avio_seek(pb, ((int64_t)wf->sectors[offset >> wf->sector_bits] << WTV_SECTOR_BITS)
- + (offset & ((1 << wf->sector_bits) - 1)), SEEK_SET) < 0;
+ seek_by_sector(pb, wf->sectors[offset >> wf->sector_bits],
+ offset & ((1 << wf->sector_bits) - 1)) < 0;
wf->position = offset;
return offset;
}
WtvFile *wf;
uint8_t *buffer;
- if (avio_seek(s->pb, first_sector << WTV_SECTOR_BITS, SEEK_SET) < 0)
+ if (seek_by_sector(s->pb, first_sector, 0) < 0)
return NULL;
wf = av_mallocz(sizeof(WtvFile));
int nb_sectors1 = read_ints(s->pb, sectors1, WTV_SECTOR_SIZE / 4);
int i;
- wf->sectors = av_malloc(nb_sectors1 << WTV_SECTOR_BITS);
+ wf->sectors = av_malloc(SHIFT_SECTOR_BITS(nb_sectors1));
if (!wf->sectors) {
av_free(wf);
return NULL;
}
wf->nb_sectors = 0;
for (i = 0; i < nb_sectors1; i++) {
- if (avio_seek(s->pb, (int64_t)sectors1[i] << WTV_SECTOR_BITS, SEEK_SET) < 0)
+ if (seek_by_sector(s->pb, sectors1[i], 0) < 0)
break;
wf->nb_sectors += read_ints(s->pb, wf->sectors + i * WTV_SECTOR_SIZE / 4, WTV_SECTOR_SIZE / 4);
}
/* seek to initial sector */
wf->position = 0;
- if (avio_seek(s->pb, (int64_t)wf->sectors[0] << WTV_SECTOR_BITS, SEEK_SET) < 0) {
+ if (seek_by_sector(s->pb, wf->sectors[0], 0) < 0) {
av_free(wf->sectors);
av_free(wf);
return NULL;
dir_length = AV_RL16(buf + 16);
file_length = AV_RL64(buf + 24);
name_size = 2 * AV_RL32(buf + 32);
- if (buf + 48 + name_size > buf_end) {
+ if (name_size < 0) {
+ av_log(s, AV_LOG_ERROR,
+ "bad filename length, remaining directory entries ignored\n");
+ break;
+ }
+ if (48 + name_size > buf_end - buf) {
av_log(s, AV_LOG_ERROR, "filename exceeds buffer size; remaining directory entries ignored\n");
break;
}
return;
if (type == 0 && length == 4) {
- snprintf(buf, buf_size, "%"PRIi32, avio_rl32(pb));
+ snprintf(buf, buf_size, "%u", avio_rl32(pb));
} else if (type == 1) {
avio_get_str16le(pb, length, buf, buf_size);
if (!strlen(buf)) {
else
snprintf(buf, buf_size, "%"PRIi64, num);
} else if (type == 5 && length == 2) {
- snprintf(buf, buf_size, "%"PRIi16, avio_rl16(pb));
+ snprintf(buf, buf_size, "%u", avio_rl16(pb));
} else if (type == 6 && length == 16) {
ff_asf_guid guid;
avio_read(pb, guid, 16);
avio_skip(s->pb, 4);
root_sector = avio_rl32(s->pb);
- avio_seek(s->pb, root_sector << WTV_SECTOR_BITS, SEEK_SET);
+ seek_by_sector(s->pb, root_sector, 0);
root_size = avio_read(s->pb, root, root_size);
if (root_size < 0)
return AVERROR_INVALIDDATA;