static int IsValidExtendedFormat(const WebPDemuxer* const dmux) { const int has_fragments = !!(dmux->feature_flags_ & FRAGMENTS_FLAG); const int has_frames = !!(dmux->feature_flags_ & ANIMATION_FLAG); const Frame* f; if (dmux->state_ == WEBP_DEMUX_PARSING_HEADER) return 1; if (dmux->canvas_width_ <= 0 || dmux->canvas_height_ <= 0) return 0; if (dmux->loop_count_ < 0) return 0; if (dmux->state_ == WEBP_DEMUX_DONE && dmux->frames_ == NULL) return 0; for (f = dmux->frames_; f != NULL; f = f->next_) { const int cur_frame_set = f->frame_num_; int frame_count = 0, fragment_count = 0; // Check frame properties and if the image is composed of fragments that // each fragment came from a fragment. for (; f != NULL && f->frame_num_ == cur_frame_set; f = f->next_) { const ChunkData* const image = f->img_components_; const ChunkData* const alpha = f->img_components_ + 1; if (!has_fragments && f->is_fragment_) return 0; if (!has_frames && f->frame_num_ > 1) return 0; if (f->complete_) { if (alpha->size_ == 0 && image->size_ == 0) return 0; // Ensure alpha precedes image bitstream. if (alpha->size_ > 0 && alpha->offset_ > image->offset_) { return 0; } if (f->width_ <= 0 || f->height_ <= 0) return 0; } else { // There shouldn't be a partial frame in a complete file. if (dmux->state_ == WEBP_DEMUX_DONE) return 0; // Ensure alpha precedes image bitstream. if (alpha->size_ > 0 && image->size_ > 0 && alpha->offset_ > image->offset_) { return 0; } // There shouldn't be any frames after an incomplete one. if (f->next_ != NULL) return 0; } if (f->width_ > 0 && f->height_ > 0 && !CheckFrameBounds(f, !(has_frames || has_fragments), dmux->canvas_width_, dmux->canvas_height_)) { return 0; } fragment_count += f->is_fragment_; ++frame_count; } if (!has_fragments && frame_count > 1) return 0; if (fragment_count > 0 && frame_count != fragment_count) return 0; if (f == NULL) break; } return 1; }
static int IsValidExtendedFormat(const WebPDemuxer* const dmux) { const int is_animation = !!(dmux->feature_flags_ & ANIMATION_FLAG); const int is_fragmented = !!(dmux->feature_flags_ & FRAGMENTS_FLAG); const Frame* f = dmux->frames_; if (dmux->state_ == WEBP_DEMUX_PARSING_HEADER) return 1; if (dmux->canvas_width_ <= 0 || dmux->canvas_height_ <= 0) return 0; if (dmux->loop_count_ < 0) return 0; if (dmux->state_ == WEBP_DEMUX_DONE && dmux->frames_ == NULL) return 0; if (is_fragmented) return 0; while (f != NULL) { const int cur_frame_set = f->frame_num_; int frame_count = 0; // Check frame properties. for (; f != NULL && f->frame_num_ == cur_frame_set; f = f->next_) { const ChunkData* const image = f->img_components_; const ChunkData* const alpha = f->img_components_ + 1; if (!is_animation && f->frame_num_ > 1) return 0; if (f->complete_) { if (alpha->size_ == 0 && image->size_ == 0) return 0; // Ensure alpha precedes image bitstream. if (alpha->size_ > 0 && alpha->offset_ > image->offset_) { return 0; } if (f->width_ <= 0 || f->height_ <= 0) return 0; } else { // There shouldn't be a partial frame in a complete file. if (dmux->state_ == WEBP_DEMUX_DONE) return 0; // Ensure alpha precedes image bitstream. if (alpha->size_ > 0 && image->size_ > 0 && alpha->offset_ > image->offset_) { return 0; } // There shouldn't be any frames after an incomplete one. if (f->next_ != NULL) return 0; } if (f->width_ > 0 && f->height_ > 0 && !CheckFrameBounds(f, !is_animation, dmux->canvas_width_, dmux->canvas_height_)) { return 0; } ++frame_count; } } return 1; }