Blame src/libbluray/bdnav/extdata_parse.c

Packit 5e46da
/*
Packit 5e46da
 * This file is part of libbluray
Packit 5e46da
 * Copyright (C) 2012  Petri Hintukainen <phintuka@users.sourceforge.net>
Packit 5e46da
 *
Packit 5e46da
 * This library is free software; you can redistribute it and/or
Packit 5e46da
 * modify it under the terms of the GNU Lesser General Public
Packit 5e46da
 * License as published by the Free Software Foundation; either
Packit 5e46da
 * version 2.1 of the License, or (at your option) any later version.
Packit 5e46da
 *
Packit 5e46da
 * This library is distributed in the hope that it will be useful,
Packit 5e46da
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 5e46da
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 5e46da
 * Lesser General Public License for more details.
Packit 5e46da
 *
Packit 5e46da
 * You should have received a copy of the GNU Lesser General Public
Packit 5e46da
 * License along with this library. If not, see
Packit 5e46da
 * <http://www.gnu.org/licenses/>.
Packit 5e46da
 */
Packit 5e46da
Packit 5e46da
#if HAVE_CONFIG_H
Packit 5e46da
#include "config.h"
Packit 5e46da
#endif
Packit 5e46da
Packit 5e46da
#include "util/bits.h"
Packit 5e46da
#include "extdata_parse.h"
Packit 5e46da
Packit 5e46da
#include <stdint.h>
Packit 5e46da
Packit 5e46da
int bdmv_parse_extension_data(BITSTREAM *bits,
Packit 5e46da
                              int start_address,
Packit 5e46da
                              int (*handler)(BITSTREAM*, int, int, void*),
Packit 5e46da
                              void *handle)
Packit 5e46da
{
Packit 5e46da
    int64_t length;
Packit 5e46da
    int num_entries, n;
Packit 5e46da
Packit 5e46da
    if (start_address < 1) return 0;
Packit 5e46da
    if (start_address > bits->end - 12) return 0;
Packit 5e46da
Packit 5e46da
    if (bs_seek_byte(bits, start_address) < 0) {
Packit 5e46da
        return 0;
Packit 5e46da
    }
Packit 5e46da
Packit 5e46da
    length      = bs_read(bits, 32); /* length of extension data block */
Packit 5e46da
    if (length < 1) return 0;
Packit 5e46da
    bs_skip(bits, 32); /* relative start address of extension data */
Packit 5e46da
    bs_skip(bits, 24); /* padding */
Packit 5e46da
    num_entries = bs_read(bits, 8);
Packit 5e46da
Packit 5e46da
    if (start_address > bits->end - 12 - num_entries * 12) return 0;
Packit 5e46da
Packit 5e46da
    for (n = 0; n < num_entries; n++) {
Packit 5e46da
        uint16_t id1       = bs_read(bits, 16);
Packit 5e46da
        uint16_t id2       = bs_read(bits, 16);
Packit 5e46da
        int64_t  ext_start = bs_read(bits, 32);
Packit 5e46da
        int64_t  ext_len   = bs_read(bits, 32);
Packit 5e46da
Packit 5e46da
        int64_t  saved_pos = bs_pos(bits) >> 3;
Packit 5e46da
Packit 5e46da
        if (ext_start + start_address + ext_len > bits->end) return 0;
Packit 5e46da
Packit 5e46da
        if (bs_seek_byte(bits, start_address + ext_start) >= 0) {
Packit 5e46da
            (handler)(bits, id1, id2, handle);
Packit 5e46da
        }
Packit 5e46da
Packit 5e46da
        if (bs_seek_byte(bits, saved_pos) < 0) {
Packit 5e46da
            return 0;
Packit 5e46da
        }
Packit 5e46da
    }
Packit 5e46da
Packit 5e46da
    return 1;
Packit 5e46da
}