/* Icecast * * This program is distributed under the GNU General Public License, version 2. * A copy of this license is included with this source. * * Copyright 2022, Philipp "ph3-der-loewe" Schafft */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include "metadata_xiph.h" #include "logging.h" #define CATMODULE "metadata-xiph" uint32_t metadata_xiph_read_u32be_unaligned(const unsigned char *in) { uint32_t ret = 0; ret += in[0]; ret <<= 8; ret += in[1]; ret <<= 8; ret += in[2]; ret <<= 8; ret += in[3]; return ret; } uint32_t metadata_xiph_read_u32le_unaligned(const unsigned char *in) { uint32_t ret = 0; ret += in[3]; ret <<= 8; ret += in[2]; ret <<= 8; ret += in[1]; ret <<= 8; ret += in[0]; return ret; } bool metadata_xiph_read_vorbis_comments(vorbis_comment *vc, const void *buffer, size_t len) { bool ret = true; size_t expected_len = 8; uint32_t vendor_len; uint32_t count; uint32_t i; char *out_buffer = NULL; size_t out_buffer_len = 0; if (!vc || !buffer || len < expected_len) return false; /* reading vendor tag and discarding it */ vendor_len = metadata_xiph_read_u32le_unaligned(buffer); expected_len += vendor_len; if (len < expected_len) return false; buffer += 4 + vendor_len; count = metadata_xiph_read_u32le_unaligned(buffer); expected_len += count * 4; if (len < expected_len) return false; buffer += 4; for (i = 0; i < count; i++) { uint32_t comment_len = metadata_xiph_read_u32le_unaligned(buffer); buffer += 4; expected_len += comment_len; if (len < expected_len) { ret = false; break; } if (out_buffer_len < comment_len || !out_buffer) { char *n_out_buffer = realloc(out_buffer, comment_len + 1); if (!n_out_buffer) { ret = false; break; } out_buffer = n_out_buffer; out_buffer_len = comment_len; } memcpy(out_buffer, buffer, comment_len); out_buffer[comment_len] = 0; buffer += comment_len; vorbis_comment_add(vc, out_buffer); } free(out_buffer); if (!ret) { vorbis_comment_clear(vc); vorbis_comment_init(vc); } return ret; }