OSDN Git Service

[flac] Update FLAC to 1.4.1
[timidity41/timidity41.git] / FLAC / src / metadata_iterators.c
index 17f25cd..168a3fb 100644 (file)
@@ -1,6 +1,6 @@
 /* libFLAC - Free Lossless Audio Codec library
  * Copyright (C) 2001-2009  Josh Coalson
- * Copyright (C) 2011-2016  Xiph.Org Foundation
+ * Copyright (C) 2011-2022  Xiph.Org Foundation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -286,26 +286,29 @@ FLAC_API FLAC__bool FLAC__metadata_get_picture(const char *filename, FLAC__Strea
        do {
                if(FLAC__metadata_simple_iterator_get_block_type(it) == FLAC__METADATA_TYPE_PICTURE) {
                        FLAC__StreamMetadata *obj = FLAC__metadata_simple_iterator_get_block(it);
-                       FLAC__uint64 area = (FLAC__uint64)obj->data.picture.width * (FLAC__uint64)obj->data.picture.height;
-                       /* check constraints */
-                       if(
-                               (type == (FLAC__StreamMetadata_Picture_Type)(-1) || type == obj->data.picture.type) &&
-                               (mime_type == 0 || !strcmp(mime_type, obj->data.picture.mime_type)) &&
-                               (description == 0 || !strcmp((const char *)description, (const char *)obj->data.picture.description)) &&
-                               obj->data.picture.width <= max_width &&
-                               obj->data.picture.height <= max_height &&
-                               obj->data.picture.depth <= max_depth &&
-                               obj->data.picture.colors <= max_colors &&
-                               (area > max_area_seen || (area == max_area_seen && obj->data.picture.depth > max_depth_seen))
-                       ) {
-                               if(*picture)
-                                       FLAC__metadata_object_delete(*picture);
-                               *picture = obj;
-                               max_area_seen = area;
-                               max_depth_seen = obj->data.picture.depth;
-                       }
-                       else {
-                               FLAC__metadata_object_delete(obj);
+                       if(0 != obj) {
+                               FLAC__uint64 area = (FLAC__uint64)obj->data.picture.width * (FLAC__uint64)obj->data.picture.height;
+
+                               /* check constraints */
+                               if(
+                                       (type == (FLAC__StreamMetadata_Picture_Type)(-1) || type == obj->data.picture.type) &&
+                                       (mime_type == 0 || !strcmp(mime_type, obj->data.picture.mime_type)) &&
+                                       (description == 0 || !strcmp((const char *)description, (const char *)obj->data.picture.description)) &&
+                                       obj->data.picture.width <= max_width &&
+                                       obj->data.picture.height <= max_height &&
+                                       obj->data.picture.depth <= max_depth &&
+                                       obj->data.picture.colors <= max_colors &&
+                                       (area > max_area_seen || (area == max_area_seen && obj->data.picture.depth > max_depth_seen))
+                               ) {
+                                       if(*picture)
+                                               FLAC__metadata_object_delete(*picture);
+                                       *picture = obj;
+                                       max_area_seen = area;
+                                       max_depth_seen = obj->data.picture.depth;
+                               }
+                               else {
+                                       FLAC__metadata_object_delete(obj);
+                               }
                        }
                }
        } while(FLAC__metadata_simple_iterator_next(it));
@@ -443,7 +446,15 @@ static FLAC__bool simple_iterator_prime_input_(FLAC__Metadata_SimpleIterator *it
                case 0:
                        iterator->depth = 0;
                        iterator->first_offset = iterator->offset[iterator->depth] = ftello(iterator->file);
-                       return read_metadata_block_header_(iterator);
+                       ret = read_metadata_block_header_(iterator);
+                       /* The first metadata block must be a streaminfo. If this is not the
+                        * case, the file is invalid and assumptions made elsewhere in the
+                        * code are invalid */
+                       if(iterator->type != FLAC__METADATA_TYPE_STREAMINFO) {
+                               iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_BAD_METADATA;
+                               return false;
+                       }
+                       return ret;
                case 1:
                        iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
                        return false;
@@ -576,7 +587,7 @@ FLAC_API off_t FLAC__metadata_simple_iterator_get_block_offset(const FLAC__Metad
        FLAC__ASSERT(0 != iterator);
        FLAC__ASSERT(0 != iterator->file);
 
-       return iterator->offset[iterator->depth];
+       return (off_t)iterator->offset[iterator->depth];
 }
 
 FLAC_API FLAC__MetadataType FLAC__metadata_simple_iterator_get_block_type(const FLAC__Metadata_SimpleIterator *iterator)
@@ -1099,6 +1110,11 @@ static FLAC__bool chain_merge_adjacent_padding_(FLAC__Metadata_Chain *chain, FLA
                return false;
 }
 
+#if defined(_MSC_VER)
+// silence three MSVC warnings 'conversion from 'conversion from 'const __int64' to 'uint32_t', possible loss of data'
+#pragma warning ( disable : 4244 )
+#endif
+
 /* Returns the new length of the chain, or 0 if there was an error. */
 /* WATCHOUT: This can get called multiple times before a write, so
  * it should still work when this happens.
@@ -1176,6 +1192,10 @@ static FLAC__off_t chain_prepare_for_write_(FLAC__Metadata_Chain *chain, FLAC__b
        return current_length;
 }
 
+#if defined(_MSC_VER)
+#pragma warning ( default : 4244 )
+#endif
+
 static FLAC__bool chain_read_cb_(FLAC__Metadata_Chain *chain, FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOCallback_Seek seek_cb, FLAC__IOCallback_Tell tell_cb)
 {
        FLAC__Metadata_Node *node;
@@ -1348,6 +1368,12 @@ static FLAC__bool chain_read_ogg_cb_(FLAC__Metadata_Chain *chain, FLAC__IOHandle
 
        chain->initial_length = chain_calculate_length_(chain);
 
+       if(chain->initial_length == 0) {
+               /* Ogg FLAC file must have at least streaminfo and vorbis comment */
+               chain->status = FLAC__METADATA_CHAIN_STATUS_BAD_METADATA;
+               return false;
+       }
+
        return true;
 }
 
@@ -1625,6 +1651,11 @@ typedef enum {
        LBS_BLOCK_REMOVED
 } LastBlockState;
 
+#if defined(_MSC_VER)
+// silence three MSVC warnings 'conversion from 'conversion from 'const __int64' to 'uint32_t', possible loss of data'
+#pragma warning ( disable : 4244 )
+#endif
+
 FLAC_API FLAC__bool FLAC__metadata_chain_check_if_tempfile_needed(FLAC__Metadata_Chain *chain, FLAC__bool use_padding)
 {
        /* This does all the same checks that are in chain_prepare_for_write_()
@@ -1702,6 +1733,10 @@ FLAC_API FLAC__bool FLAC__metadata_chain_check_if_tempfile_needed(FLAC__Metadata
        return (current_length != chain->initial_length);
 }
 
+#if defined(_MSC_VER)
+#pragma warning ( default : 4244 )
+#endif
+
 FLAC_API FLAC__bool FLAC__metadata_chain_write(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__bool preserve_file_stats)
 {
        struct flac_stat_s stats;
@@ -2284,18 +2319,13 @@ FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_vorbis_comment_entr
        if(0 != entry->entry)
                free(entry->entry);
 
-       if(entry->length == 0) {
-               entry->entry = 0;
-       }
-       else {
-               if(0 == (entry->entry = safe_malloc_add_2op_(entry->length, /*+*/1)))
-                       return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
+       if(0 == (entry->entry = safe_malloc_add_2op_(entry->length, /*+*/1)))
+               return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
 
-               if(read_cb(entry->entry, 1, entry->length, handle) != entry->length)
-                       return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
+       if(entry->length > 0 && read_cb(entry->entry, 1, entry->length, handle) != entry->length)
+               return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
 
-               entry->entry[entry->length] = '\0';
-       }
+       entry->entry[entry->length] = '\0';
 
        return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK;
 }
@@ -2326,6 +2356,11 @@ FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_vorbis_comment_cb_(
        if(block->num_comments == 0) {
                block->comments = 0;
        }
+       else if(block->num_comments > (block_length >> 2)) { /* each comment needs at least 4 byte */
+               block->num_comments = 0;
+               status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_BAD_METADATA;
+               goto skip;
+       }
        else if(0 == (block->comments = calloc(block->num_comments, sizeof(FLAC__StreamMetadata_VorbisComment_Entry)))) {
                block->num_comments = 0;
                return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR;
@@ -2482,6 +2517,9 @@ static FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_picture_cstr
                return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR;
        *length = unpack_uint32_(buffer, length_len);
 
+       if(*length > (1u << FLAC__STREAM_METADATA_LENGTH_LEN)) /* data cannot be larger than FLAC metadata block */
+               return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_BAD_METADATA;
+
        if(0 != *data)
                free(*data);
 
@@ -3422,7 +3460,7 @@ FLAC__bool get_file_stats_(const char *filename, struct flac_stat_s *stats)
 
 void set_file_stats_(const char *filename, struct flac_stat_s *stats)
 {
-#if defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200809L)
+#if defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200809L) && !defined(_WIN32)
        struct timespec srctime[2] = {};
        srctime[0].tv_sec = stats->st_atime;
        srctime[1].tv_sec = stats->st_mtime;