static bool_t read_frame (VFSFile * handle, int max_size, int version, bool_t syncsafe, int * frame_size, char * key, char * * data, int * size) { ID3v2FrameHeader header; int skip = 0; if ((max_size -= sizeof (ID3v2FrameHeader)) < 0) return FALSE; if (vfs_fread (& header, 1, sizeof (ID3v2FrameHeader), handle) != sizeof (ID3v2FrameHeader)) return FALSE; if (! header.key[0]) /* padding */ return FALSE; header.size = (version == 3) ? GUINT32_FROM_BE (header.size) : unsyncsafe32 (GUINT32_FROM_BE (header.size)); header.flags = GUINT16_FROM_BE (header.flags); if (header.size > max_size || header.size == 0) return FALSE; TAGDBG ("Found frame:\n"); TAGDBG (" key = %.4s\n", header.key); TAGDBG (" size = %d\n", (int) header.size); TAGDBG (" flags = %x\n", (int) header.flags); * frame_size = sizeof (ID3v2FrameHeader) + header.size; g_strlcpy (key, header.key, 5); if (header.flags & (ID3_FRAME_COMPRESSED | ID3_FRAME_ENCRYPTED)) { TAGDBG ("Hit compressed/encrypted frame %s.\n", key); return FALSE; } if (header.flags & ID3_FRAME_HAS_GROUP) skip ++; if (header.flags & ID3_FRAME_HAS_LENGTH) skip += 4; if ((skip > 0 && vfs_fseek (handle, skip, SEEK_CUR)) || skip >= header.size) return FALSE; * size = header.size - skip; * data = g_malloc (* size); if (vfs_fread (* data, 1, * size, handle) != * size) return FALSE; if (syncsafe || (header.flags & ID3_FRAME_SYNCSAFE)) * size = unsyncsafe (* data, * size); TAGDBG ("Data size = %d.\n", * size); return TRUE; }
static bool_t skip_extended_header_4 (VFSFile * handle, int * _size) { uint32_t size; if (vfs_fread (& size, 1, 4, handle) != 4) return FALSE; size = unsyncsafe32 (GUINT32_FROM_BE (size)); TAGDBG ("Found v2.4 extended header, size = %d.\n", (int) size); if (vfs_fseek (handle, size - 4, SEEK_CUR)) return FALSE; * _size = size; return TRUE; }
static gboolean validate_header (ID3v2Header * header) { if (memcmp (header->magic, "ID3", 3)) return FALSE; if ((header->version != 2)) return FALSE; header->size = unsyncsafe32(GUINT32_FROM_BE(header->size)); TAGDBG ("Found ID3v2 header:\n"); TAGDBG (" magic = %.3s\n", header->magic); TAGDBG (" version = %d\n", (gint) header->version); TAGDBG (" revision = %d\n", (gint) header->revision); TAGDBG (" flags = %x\n", (gint) header->flags); TAGDBG (" size = %d\n", (gint) header->size); return TRUE; }
static bool_t validate_header (ID3v2Header * header, bool_t is_footer) { if (memcmp (header->magic, is_footer ? "3DI" : "ID3", 3)) return FALSE; if ((header->version != 3 && header->version != 4) || header->revision != 0) return FALSE; header->size = unsyncsafe32 (GUINT32_FROM_BE (header->size)); TAGDBG ("Found ID3v2 %s:\n", is_footer ? "footer" : "header"); TAGDBG (" magic = %.3s\n", header->magic); TAGDBG (" version = %d\n", (int) header->version); TAGDBG (" revision = %d\n", (int) header->revision); TAGDBG (" flags = %x\n", (int) header->flags); TAGDBG (" size = %d\n", (int) header->size); return TRUE; }