Commit def597ee authored by Josh Coalson's avatar Josh Coalson

additions to metadata object api: more vorbiscomment functions, trailing-null...

additions to metadata object api: more vorbiscomment functions, trailing-null on vorbis comment field values enforced everywhere
parent 8ddf7fb2
......@@ -84,6 +84,95 @@
This is an informal changelog, a summary of changes in each release. Particulary important for developers is the precise description of changes to the library interfaces.
</P>
<P>
<A NAME="flac_@@@@@@"><B>@@@@@@</B></A>
</P>
<P>
<UL>
<LI>
General:
<UL>
</UL>
</LI>
<LI>
FLAC format:
<UL>
</UL>
</LI>
<LI>
Ogg FLAC format:
<UL>
</UL>
</LI>
<LI>
flac:
<UL>
<LI>New option <A HREF="documentation.html#flac_options_input_size"><TT>--input-size</TT></A> to manually specify the input size when encoding raw samples from stdin.</LI>
</UL>
</LI>
<LI>
metaflac:
<UL>
</UL>
</LI>
<LI>
plugins:
<UL>
<LI>Added support for HTTP streaming in XMMS plugin.</LI>
</UL>
</LI>
<LI>
build system:
<UL>
</UL>
</LI>
<LI>
libraries:
<UL>
<LI>libFLAC, libOggFLAC: Can now be compiled to use only integer instructions, including encoding. The decoder is almost completely integer anyway but there were a couple places that needed a fixed-point replacement. There is no fixed-point version of LPC analysis yet, so if libFLAC is compiled integer-only, it will behave as if the max LPC order is 0 (i.e. used fixed predictors only).</LI>
</UL>
</LI>
<LI>
Interface changes:
<UL>
<LI>
libFLAC:
<UL>
<LI>Metadata interface now maintains a trailing NULL on Vorbis comment entries for convenience.</LI>
<LI><B>Added</B> FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair()</LI>
<LI><B>Added</B> FLAC__metadata_object_vorbiscomment_entry_to_name_value_pair()</LI>
<LI><B>Changed</B> the signature of FLAC__metadata_object_vorbiscomment_entry_matches(): the first argument is now <TT>FLAC__StreamMetadata_VorbisComment_Entry entry</TT> (was <TT>const FLAC__StreamMetadata_VorbisComment_Entry *entry</TT>), i.e. <TT>entry</TT> is now pass-by-value.</LI>
</UL>
</LI>
<LI>
libFLAC++:
<UL>
<LI>Metadata interface now maintains a trailing NULL on Vorbis comment values for convenience.</LI>
<LI><B>Added</B> methods to FLAC::Metadata::VorbisComment::Entry for setting comment values from null-terminated strings:
<UL>
<LI>Entry(const char *field)</LI>
<LI>Entry(const char *field_name, const char *field_value)</LI>
<LI>bool set_field(const char *field)</LI>
<LI>bool set_field_value(const char *field_value)</LI>
</UL>
</LI>
</UL>
</LI>
<LI>
libOggFLAC:
<UL>
</UL>
</LI>
<LI>
libOggFLAC++:
<UL>
</UL>
</LI>
</UL>
</LI>
</UL>
</P>
<P>
<A NAME="flac_1_1_1"><B>FLAC 1.1.1</B></A>
</P>
......
......@@ -492,9 +492,10 @@ namespace FLAC {
* name is undefined; only the field value is relevant.
*
* A \a field as used in the methods refers to an
* entire 'NAME=VALUE' string; the string is not null-
* terminated and a length field is required since the
* string may contain embedded nulls.
* entire 'NAME=VALUE' string; for convenience the
* string is null-terminated. A length field is
* required in the unlikely event that the value
* contains contain embedded nulls.
*
* A \a field_name is what is on the left side of the
* first '=' in the \a field. By definition it is ASCII
......@@ -505,7 +506,10 @@ namespace FLAC {
* A \a field_value is what is on the right side of the
* first '=' in the \a field. By definition, this may
* contain embedded nulls and so a \a field_value_length
* is requires to describe it.
* is required to describe it. However in practice,
* embedded nulls are not known to be used, so it is
* generally safe to treat field values as null-
* terminated UTF-8 strings.
*
* Always check is_valid() after the constructor or operator=
* to make sure memory was properly allocated.
......@@ -513,9 +517,15 @@ namespace FLAC {
class FLACPP_API Entry {
public:
Entry();
Entry(const char *field, unsigned field_length);
Entry(const char *field); // assumes \a field is null-terminated
Entry(const char *field_name, const char *field_value, unsigned field_value_length);
Entry(const char *field_name, const char *field_value); // assumes \a field_value is null-terminated
Entry(const Entry &entry);
void operator=(const Entry &entry);
virtual ~Entry();
......@@ -532,8 +542,10 @@ namespace FLAC {
const char *get_field_value() const;
bool set_field(const char *field, unsigned field_length);
bool set_field(const char *field); // assumes \a field is null-terminated
bool set_field_name(const char *field_name);
bool set_field_value(const char *field_value, unsigned field_value_length);
bool set_field_value(const char *field_value); // assumes \a field_value is null-terminated
protected:
bool is_valid_;
::FLAC__StreamMetadata_VorbisComment_Entry entry_;
......@@ -548,7 +560,9 @@ namespace FLAC {
void clear_field_name();
void clear_field_value();
void construct(const char *field, unsigned field_length);
void construct(const char *field); // assumes \a field is null-terminated
void construct(const char *field_name, const char *field_value, unsigned field_value_length);
void construct(const char *field_name, const char *field_value); // assumes \a field_value is null-terminated
void compose_field();
void parse_field();
};
......@@ -606,6 +620,9 @@ namespace FLAC {
//! See FLAC__metadata_object_vorbiscomment_insert_comment()
bool insert_comment(unsigned index, const Entry &entry);
//! See FLAC__metadata_object_vorbiscomment_append_comment()
bool append_comment(const Entry &entry);
//! See FLAC__metadata_object_vorbiscomment_delete_comment()
bool delete_comment(unsigned index);
};
......
......@@ -583,6 +583,15 @@ typedef struct {
/** Vorbis comment entry structure used in VORBIS_COMMENT blocks. (c.f. <A HREF="../format.html#metadata_block_vorbis_comment">format specification</A>)
*
* For convenience, the APIs maintain a trailing NUL character at the end of
* \a entry which is not counted toward \a length or stored in the stream,
* i.e.
* \code strlen(entry) == length \endcode
*
* It's recommended but not required for users to follow this convention as
* well when dealing directly with FLAC__StreamMetadata_VorbisComment_Entry
* as it makes dealing with plain strings easier.
*/
typedef struct {
FLAC__uint32 length;
......
This diff is collapsed.
......@@ -122,7 +122,7 @@ static FLAC__bool set_vc_field(FLAC__StreamMetadata *block, const Argument_VcFie
entry.length = strlen((const char *)entry.entry);
if(!FLAC__metadata_object_vorbiscomment_insert_comment(block, block->data.vorbis_comment.num_comments, entry, /*copy=*/true)) {
if(!FLAC__metadata_object_vorbiscomment_append_comment(block, entry, /*copy=*/true)) {
if(needs_free)
free(converted);
*violation = "memory allocation failure";
......
......@@ -461,12 +461,24 @@ namespace FLAC {
construct(field, field_length);
}
VorbisComment::Entry::Entry(const char *field)
{
zero();
construct(field);
}
VorbisComment::Entry::Entry(const char *field_name, const char *field_value, unsigned field_value_length)
{
zero();
construct(field_name, field_value, field_value_length);
}
VorbisComment::Entry::Entry(const char *field_name, const char *field_value)
{
zero();
construct(field_name, field_value);
}
VorbisComment::Entry::Entry(const Entry &entry)
{
FLAC__ASSERT(entry.is_valid());
......@@ -540,18 +552,24 @@ namespace FLAC {
clear_entry();
if(0 == (entry_.entry = (FLAC__byte*)malloc(field_length))) {
if(0 == (entry_.entry = (FLAC__byte*)malloc(field_length+1))) {
is_valid_ = false;
}
else {
entry_.length = field_length;
memcpy(entry_.entry, field, field_length);
entry_.entry[field_length] = '\0';
(void) parse_field();
}
return is_valid_;
}
bool VorbisComment::Entry::set_field(const char *field)
{
return set_field(field, strlen(field));
}
bool VorbisComment::Entry::set_field_name(const char *field_name)
{
FLAC__ASSERT(is_valid());
......@@ -577,18 +595,24 @@ namespace FLAC {
clear_field_value();
if(0 == (field_value_ = (char *)malloc(field_value_length))) {
if(0 == (field_value_ = (char *)malloc(field_value_length+1))) {
is_valid_ = false;
}
else {
field_value_length_ = field_value_length;
memcpy(field_value_, field_value, field_value_length);
field_value_[field_value_length] = '\0';
compose_field();
}
return is_valid_;
}
bool VorbisComment::Entry::set_field_value(const char *field_value)
{
return set_field_value(field_value, strlen(field_value));
}
void VorbisComment::Entry::zero()
{
is_valid_ = true;
......@@ -641,17 +665,27 @@ namespace FLAC {
parse_field();
}
void VorbisComment::Entry::construct(const char *field)
{
construct(field, strlen(field));
}
void VorbisComment::Entry::construct(const char *field_name, const char *field_value, unsigned field_value_length)
{
if(set_field_name(field_name) && set_field_value(field_value, field_value_length))
compose_field();
}
void VorbisComment::Entry::construct(const char *field_name, const char *field_value)
{
construct(field_name, field_value, strlen(field_value));
}
void VorbisComment::Entry::compose_field()
{
clear_entry();
if(0 == (entry_.entry = (FLAC__byte*)malloc(field_name_length_ + 1 + field_value_length_))) {
if(0 == (entry_.entry = (FLAC__byte*)malloc(field_name_length_ + 1 + field_value_length_ + 1))) {
is_valid_ = false;
}
else {
......@@ -661,6 +695,7 @@ namespace FLAC {
entry_.length += 1;
memcpy(entry_.entry + entry_.length, field_value_, field_value_length_);
entry_.length += field_value_length_;
entry_.entry[entry_.length] = '\0';
is_valid_ = true;
}
}
......@@ -692,11 +727,12 @@ namespace FLAC {
}
else {
field_value_length_ = entry_.length - field_name_length_ - 1;
if(0 == (field_value_ = (char *)malloc(field_value_length_))) {
if(0 == (field_value_ = (char *)malloc(field_value_length_ + 1))) { // +1 for the trailing \0
is_valid_ = false;
return;
}
memcpy(field_value_, ++p, field_value_length_);
field_value_[field_value_length_] = '\0';
}
is_valid_ = true;
......@@ -757,6 +793,12 @@ namespace FLAC {
return (bool)::FLAC__metadata_object_vorbiscomment_insert_comment(object_, index, entry.get_entry(), /*copy=*/true);
}
bool VorbisComment::append_comment(const VorbisComment::Entry &entry)
{
FLAC__ASSERT(is_valid());
return (bool)::FLAC__metadata_object_vorbiscomment_append_comment(object_, entry.get_entry(), /*copy=*/true);
}
bool VorbisComment::delete_comment(unsigned index)
{
FLAC__ASSERT(is_valid());
......
......@@ -1982,11 +1982,13 @@ FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_vorbis_comment_entr
entry->entry = 0;
}
else {
if(0 == (entry->entry = (FLAC__byte*)malloc(entry->length)))
if(0 == (entry->entry = (FLAC__byte*)malloc(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;
entry->entry[entry->length] = '\0';
}
return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK;
......
This diff is collapsed.
......@@ -1167,12 +1167,13 @@ FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__Stre
if(!FLAC__bitbuffer_read_raw_uint32_little_endian(decoder->private_->input, &obj->vendor_string.length, read_callback_, decoder))
return false; /* the read_callback_ sets the state for us */
if(obj->vendor_string.length > 0) {
if(0 == (obj->vendor_string.entry = (FLAC__byte*)malloc(obj->vendor_string.length))) {
if(0 == (obj->vendor_string.entry = (FLAC__byte*)malloc(obj->vendor_string.length+1))) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false;
}
if(!FLAC__bitbuffer_read_byte_block_aligned_no_crc(decoder->private_->input, obj->vendor_string.entry, obj->vendor_string.length, read_callback_, decoder))
return false; /* the read_callback_ sets the state for us */
obj->vendor_string.entry[obj->vendor_string.length] = '\0';
}
else
obj->vendor_string.entry = 0;
......@@ -1193,12 +1194,13 @@ FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__Stre
if(!FLAC__bitbuffer_read_raw_uint32_little_endian(decoder->private_->input, &obj->comments[i].length, read_callback_, decoder))
return false; /* the read_callback_ sets the state for us */
if(obj->comments[i].length > 0) {
if(0 == (obj->comments[i].entry = (FLAC__byte*)malloc(obj->comments[i].length))) {
if(0 == (obj->comments[i].entry = (FLAC__byte*)malloc(obj->comments[i].length+1))) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false;
}
if(!FLAC__bitbuffer_read_byte_block_aligned_no_crc(decoder->private_->input, obj->comments[i].entry, obj->comments[i].length, read_callback_, decoder))
return false; /* the read_callback_ sets the state for us */
obj->comments[i].entry[obj->comments[i].length] = '\0';
}
else
obj->comments[i].entry = 0;
......
......@@ -192,7 +192,7 @@ FLAC__bool set_vc_field(const char *filename, FLAC__StreamMetadata *block, const
entry.length = strlen((const char *)entry.entry);
if(!FLAC__metadata_object_vorbiscomment_insert_comment(block, block->data.vorbis_comment.num_comments, entry, /*copy=*/true)) {
if(!FLAC__metadata_object_vorbiscomment_append_comment(block, entry, /*copy=*/true)) {
if(needs_free)
free(converted);
fprintf(stderr, "%s: ERROR: memory allocation failure\n", filename);
......
......@@ -220,24 +220,16 @@ void write_vc_field(const char *filename, const FLAC__StreamMetadata_VorbisComme
if(!raw) {
/*
* utf8_decode() works on NULL-terminated strings, so
* we append a null to the entry. @@@ Note, this means
* that comments that contain an embedded null will be
* truncated by utf_decode().
* WATCHOUT: comments that contain an embedded null will
* be truncated by utf_decode().
*/
char *terminated, *converted;
char *converted;
if(0 == (terminated = malloc(entry->length + 1)))
die("out of memory allocating space for vorbis comment");
memcpy(terminated, entry->entry, entry->length);
terminated[entry->length] = '\0';
if(utf8_decode(terminated, &converted) >= 0) {
if(utf8_decode(entry->entry, &converted) >= 0) {
(void) local_fwrite(converted, 1, strlen(converted), f);
free(terminated);
free(converted);
}
else {
free(terminated);
(void) local_fwrite(entry->entry, 1, entry->length, f);
}
}
......@@ -246,7 +238,7 @@ void write_vc_field(const char *filename, const FLAC__StreamMetadata_VorbisComme
}
}
fprintf(f, "\n");
putc('\n', f);
}
void write_vc_fields(const char *filename, const char *field_name, const FLAC__StreamMetadata_VorbisComment_Entry entry[], unsigned num_entries, FLAC__bool raw, FILE *f)
......@@ -255,7 +247,7 @@ void write_vc_fields(const char *filename, const char *field_name, const FLAC__S
const unsigned field_name_length = (0 != field_name)? strlen(field_name) : 0;
for(i = 0; i < num_entries; i++) {
if(0 == field_name || FLAC__metadata_object_vorbiscomment_entry_matches(entry + i, field_name, field_name_length))
if(0 == field_name || FLAC__metadata_object_vorbiscomment_entry_matches(entry[i], field_name, field_name_length))
write_vc_field(filename, entry + i, raw, f);
}
}
......@@ -102,7 +102,7 @@ static FLAC__bool append_tag_(FLAC__StreamMetadata *block, const char *format, c
entry.entry = (FLAC__byte *)buffer;
entry.length = strlen(buffer);
return FLAC__metadata_object_vorbiscomment_insert_comment(block, block->data.vorbis_comment.num_comments, entry, /*copy=*/true);
return FLAC__metadata_object_vorbiscomment_append_comment(block, entry, /*copy=*/true);
}
FLAC__bool grabbag__replaygain_is_valid_sample_frequency(unsigned sample_frequency)
......
......@@ -500,8 +500,8 @@ static bool generate_file_()
vorbiscomment.type = FLAC__METADATA_TYPE_VORBIS_COMMENT;
vorbiscomment.length = (4 + vendor_string_length) + 4;
vorbiscomment.data.vorbis_comment.vendor_string.length = vendor_string_length;
vorbiscomment.data.vorbis_comment.vendor_string.entry = (FLAC__byte*)malloc_or_die_(vendor_string_length);
memcpy(vorbiscomment.data.vorbis_comment.vendor_string.entry, FLAC__VENDOR_STRING, vendor_string_length);
vorbiscomment.data.vorbis_comment.vendor_string.entry = (FLAC__byte*)malloc_or_die_(vendor_string_length+1);
memcpy(vorbiscomment.data.vorbis_comment.vendor_string.entry, FLAC__VENDOR_STRING, vendor_string_length+1);
vorbiscomment.data.vorbis_comment.num_comments = 0;
vorbiscomment.data.vorbis_comment.comments = 0;
}
......
......@@ -120,16 +120,16 @@ static void init_metadata_blocks_()
vorbiscomment_.type = ::FLAC__METADATA_TYPE_VORBIS_COMMENT;
vorbiscomment_.length = (4 + 5) + 4 + (4 + 12) + (4 + 12);
vorbiscomment_.data.vorbis_comment.vendor_string.length = 5;
vorbiscomment_.data.vorbis_comment.vendor_string.entry = (FLAC__byte*)malloc_or_die_(5);
memcpy(vorbiscomment_.data.vorbis_comment.vendor_string.entry, "name0", 5);
vorbiscomment_.data.vorbis_comment.vendor_string.entry = (FLAC__byte*)malloc_or_die_(5+1);
memcpy(vorbiscomment_.data.vorbis_comment.vendor_string.entry, "name0", 5+1);
vorbiscomment_.data.vorbis_comment.num_comments = 2;
vorbiscomment_.data.vorbis_comment.comments = (::FLAC__StreamMetadata_VorbisComment_Entry*)malloc_or_die_(vorbiscomment_.data.vorbis_comment.num_comments * sizeof(::FLAC__StreamMetadata_VorbisComment_Entry));
vorbiscomment_.data.vorbis_comment.comments[0].length = 12;
vorbiscomment_.data.vorbis_comment.comments[0].entry = (FLAC__byte*)malloc_or_die_(12);
memcpy(vorbiscomment_.data.vorbis_comment.comments[0].entry, "name2=value2", 12);
vorbiscomment_.data.vorbis_comment.comments[0].entry = (FLAC__byte*)malloc_or_die_(12+1);
memcpy(vorbiscomment_.data.vorbis_comment.comments[0].entry, "name2=value2", 12+1);
vorbiscomment_.data.vorbis_comment.comments[1].length = 12;
vorbiscomment_.data.vorbis_comment.comments[1].entry = (FLAC__byte*)malloc_or_die_(12);
memcpy(vorbiscomment_.data.vorbis_comment.comments[1].entry, "name3=value3", 12);
vorbiscomment_.data.vorbis_comment.comments[1].entry = (FLAC__byte*)malloc_or_die_(12+1);
memcpy(vorbiscomment_.data.vorbis_comment.comments[1].entry, "name3=value3", 12+1);
cuesheet_.is_last = true;
cuesheet_.type = ::FLAC__METADATA_TYPE_CUESHEET;
......@@ -795,12 +795,32 @@ bool test_metadata_object_vorbiscomment()
return die_("!is_valid()");
printf("OK\n");
{
printf("testing Entry::Entry(const char *field)... ");
FLAC::Metadata::VorbisComment::Entry entry2z("name2=value2");
if(!entry2z.is_valid())
return die_("!is_valid()");
if(strcmp(entry2.get_field(), entry2z.get_field()))
return die_("bad value");
printf("OK\n");
}
printf("testing Entry::Entry(const char *field_name, const char *field_value, unsigned field_value_length)... ");
FLAC::Metadata::VorbisComment::Entry entry3("name3", "value3", strlen("value3"));
if(!entry3.is_valid())
return die_("!is_valid()");
printf("OK\n");
{
printf("testing Entry::Entry(const char *field_name, const char *field_value)... ");
FLAC::Metadata::VorbisComment::Entry entry3z("name3", "value3");
if(!entry3z.is_valid())
return die_("!is_valid()");
if(strcmp(entry3.get_field(), entry3z.get_field()))
return die_("bad value");
printf("OK\n");
}
printf("testing Entry::Entry(const Entry &entry)... ");
{
FLAC::Metadata::VorbisComment::Entry entry2copy(entry2);
......@@ -867,7 +887,7 @@ bool test_metadata_object_vorbiscomment()
return die_("entry mismatch");
printf("OK\n");
printf("testing Entry::set_field_value()... ");
printf("testing Entry::set_field_value(const char *field_value, unsigned field_value_length)... ");
if(!entry1.set_field_value("value1", strlen("value1")))
return die_("returned false");
if(0 != memcmp(entry1.get_field_value(), "value1", strlen("value1")))
......@@ -876,7 +896,16 @@ bool test_metadata_object_vorbiscomment()
return die_("entry mismatch");
printf("OK\n");
printf("testing Entry::set_field()... ");
printf("testing Entry::set_field_value(const char *field_value)... ");
if(!entry1.set_field_value("value1"))
return die_("returned false");
if(0 != memcmp(entry1.get_field_value(), "value1", strlen("value1")))
return die_("value mismatch");
if(0 != memcmp(entry1.get_field(), "name1=value1", strlen("name1=value1")))
return die_("entry mismatch");
printf("OK\n");
printf("testing Entry::set_field(const char *field, unsigned field_length)... ");
if(!entry1.set_field("name0=value0", strlen("name0=value0")))
return die_("returned false");
if(0 != memcmp(entry1.get_field_name(), "name0", strlen("name0")))
......@@ -887,6 +916,17 @@ bool test_metadata_object_vorbiscomment()
return die_("entry mismatch");
printf("OK\n");
printf("testing Entry::set_field(const char *field)... ");
if(!entry1.set_field("name0=value0"))
return die_("returned false");
if(0 != memcmp(entry1.get_field_name(), "name0", strlen("name0")))
return die_("value mismatch");
if(0 != memcmp(entry1.get_field_value(), "value0", strlen("value0")))
return die_("value mismatch");
if(0 != memcmp(entry1.get_field(), "name0=value0", strlen("name0=value0")))
return die_("entry mismatch");
printf("OK\n");
printf("PASSED\n\n");
......@@ -989,6 +1029,44 @@ bool test_metadata_object_vorbiscomment()
return die_("value mismatch");
printf("OK\n");
printf("testing VorbisComment::append_comment()... +\n");
printf(" VorbisComment::get_comment()... ");
if(!block.append_comment(entry3))
return die_("returned false");
if(block.get_comment(0).get_field_length() != vorbiscomment_.data.vorbis_comment.comments[1].length)
return die_("length mismatch");
if(0 != memcmp(block.get_comment(0).get_field(), vorbiscomment_.data.vorbis_comment.comments[1].entry, vorbiscomment_.data.vorbis_comment.comments[1].length))
return die_("value mismatch");
printf("OK\n");
printf("testing VorbisComment::append_comment()... +\n");
printf(" VorbisComment::get_comment()... ");
if(!block.append_comment(entry2))
return die_("returned false");
if(block.get_comment(1).get_field_length() != vorbiscomment_.data.vorbis_comment.comments[0].length)
return die_("length mismatch");
if(0 != memcmp(block.get_comment(1).get_field(), vorbiscomment_.data.vorbis_comment.comments[0].entry, vorbiscomment_.data.vorbis_comment.comments[0].length))
return die_("value mismatch");
printf("OK\n");
printf("testing VorbisComment::delete_comment()... +\n");
printf(" VorbisComment::get_comment()... ");
if(!block.delete_comment(0))
return die_("returned false");
if(block.get_comment(0).get_field_length() != vorbiscomment_.data.vorbis_comment.comments[0].length)
return die_("length[0] mismatch");
if(0 != memcmp(block.get_comment(0).get_field(), vorbiscomment_.data.vorbis_comment.comments[0].entry, vorbiscomment_.data.vorbis_comment.comments[0].length))
return die_("value[0] mismatch");
printf("OK\n");
printf("testing VorbisComment::delete_comment()... +\n");
printf(" VorbisComment::get_comment()... ");
if(!block.delete_comment(0))
return die_("returned false");
if(block.get_num_comments() != 0)
return die_("block mismatch, expected num_comments = 0");
printf("OK\n");
printf("testing VorbisComment::insert_comment()... +\n");
printf(" VorbisComment::get_comment()... ");
if(!block.insert_comment(0, entry3))
......
......@@ -429,13 +429,13 @@ void mutils__init_metadata_blocks(
vorbiscomment->type = FLAC__METADATA_TYPE_VORBIS_COMMENT;
vorbiscomment->length = (4 + vendor_string_length) + 4 + (4 + 5) + (4 + 0);
vorbiscomment->data.vorbis_comment.vendor_string.length = vendor_string_length;
vorbiscomment->data.vorbis_comment.vendor_string.entry = (FLAC__byte*)malloc_or_die_(vendor_string_length);
memcpy(vorbiscomment->data.vorbis_comment.vendor_string.entry, FLAC__VENDOR_STRING, vendor_string_length);
vorbiscomment->data.vorbis_comment.vendor_string.entry = (FLAC__byte*)malloc_or_die_(vendor_string_length+1);
memcpy(vorbiscomment->data.vorbis_comment.vendor_string.entry, FLAC__VENDOR_STRING, vendor_string_length+1);
vorbiscomment->data.vorbis_comment.num_comments = 2;
vorbiscomment->data.vorbis_comment.comments = (FLAC__StreamMetadata_VorbisComment_Entry*)malloc_or_die_(vorbiscomment->data.vorbis_comment.num_comments * sizeof(FLAC__StreamMetadata_VorbisComment_Entry));
vorbiscomment->data.vorbis_comment.comments[0].length = 5;
vorbiscomment->data.vorbis_comment.comments[0].entry = (FLAC__byte*)malloc_or_die_(5);
memcpy(vorbiscomment->data.vorbis_comment.comments[0].entry, "ab=cd", 5);
vorbiscomment->data.vorbis_comment.comments[0].entry = (FLAC__byte*)malloc_or_die_(5+1);
memcpy(vorbiscomment->data.vorbis_comment.comments[0].entry, "ab=cd", 5+1);
vorbiscomment->data.vorbis_comment.comments[1].length = 0;
vorbiscomment->data.vorbis_comment.comments[1].entry = 0;
}
......
......@@ -507,8 +507,8 @@ static FLAC__bool generate_file_()
vorbiscomment.type = FLAC__METADATA_TYPE_VORBIS_COMMENT;
vorbiscomment.length = (4 + vendor_string_length) + 4;
vorbiscomment.data.vorbis_comment.vendor_string.length = vendor_string_length;
vorbiscomment.data.vorbis_comment.vendor_string.entry = malloc_or_die_(vendor_string_length);
memcpy(vorbiscomment.data.vorbis_comment.vendor_string.entry, FLAC__VENDOR_STRING, vendor_string_length);
vorbiscomment.data.vorbis_comment.vendor_string.entry = malloc_or_die_(vendor_string_length+1);
memcpy(vorbiscomment.data.vorbis_comment.vendor_string.entry, FLAC__VENDOR_STRING, vendor_string_length+1);
vorbiscomment.data.vorbis_comment.num_comments = 0;
vorbiscomment.data.vorbis_comment.comments = 0;
}
......
This diff is collapsed.
......@@ -429,13 +429,13 @@ void mutils__init_metadata_blocks(
vorbiscomment->type = FLAC__METADATA_TYPE_VORBIS_COMMENT;
vorbiscomment->length = (4 + vendor_string_length) + 4 + (4 + 5) + (4 + 0);
vorbiscomment->data.vorbis_comment.vendor_string.length = vendor_string_length;
vorbiscomment->data.vorbis_comment.vendor_string.entry = (FLAC__byte*)malloc_or_die_(vendor_string_length);
memcpy(vorbiscomment->data.vorbis_comment.vendor_string.entry, FLAC__VENDOR_STRING, vendor_string_length);
vorbiscomment->data.vorbis_comment.vendor_string.entry = (FLAC__byte*)malloc_or_die_(vendor_string_length+1);
memcpy(vorbiscomment->data.vorbis_comment.vendor_string.entry, FLAC__VENDOR_STRING, vendor_string_length+1);
vorbiscomment->data.vorbis_comment.num_comments = 2;
vorbiscomment->data.vorbis_comment.comments = (FLAC__StreamMetadata_VorbisComment_Entry*)malloc_or_die_(vorbiscomment->data.vorbis_comment.num_comments * sizeof(FLAC__StreamMetadata_VorbisComment_Entry));
vorbiscomment->data.vorbis_comment.comments[0].length = 5;
vorbiscomment->data.vorbis_comment.comments[0].entry = (FLAC__byte*)malloc_or_die_(5);
memcpy(vorbiscomment->data.vorbis_comment.comments[0].entry, "ab=cd", 5);
vorbiscomment->data.vorbis_comment.comments[0].entry = (FLAC__byte*)malloc_or_die_(5+1);
memcpy(vorbiscomment->data.vorbis_comment.comments[0].entry, "ab=cd", 5+1);
vorbiscomment->data.vorbis_comment.comments[1].length = 0;
vorbiscomment->data.vorbis_comment.comments[1].entry = 0;
}
......