~ubuntu-branches/ubuntu/lucid/flac/lucid-security

« back to all changes in this revision

Viewing changes to src/flac/vorbiscomment.c

  • Committer: Bazaar Package Importer
  • Author(s): Joshua Kwan
  • Date: 2007-05-29 22:56:36 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20070529225636-ljeff8xxip09qaap
Tags: 1.1.4-1
* New upstream release. closes: #405167, #411311
  - libOggFLAC and libOggFLAC++ have been merged into libFLAC, so
    remove their corresponding packages.
  - Because of the API changes required to effect the above, there has
    been yet another soname bump. libflac7 -> libflac8 and
    libflac++5 -> libflac++6. Emails have been dispatched to the
    maintainers of dependent packages.
* Some notes on patches that were removed:
  - 02_stdin_stdout, 06_manpage_mention_utf8_convert: merged upstream
  - 08_manpage_warnings: Upstream has changed the manpage so it defintely
    can't fit in in 80 cols, so just forget about it. We'll live.
  - 05_eof_warnings_are_errors: Upstream decided to add a -w option to
    flac to treat all warnings as errors. I am going to defer to that
    for now, but if people think it's stupid let me know and I'll port
    the patch forward.
  - 04_stack_smasher: was a backport from 1.1.3, so it's obsolete.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* flac - Command-line FLAC encoder/decoder
2
 
 * Copyright (C) 2002,2003,2004,2005  Josh Coalson
 
2
 * Copyright (C) 2002,2003,2004,2005,2006,2007  Josh Coalson
3
3
 *
4
4
 * This program is free software; you can redistribute it and/or
5
5
 * modify it under the terms of the GNU General Public License
23
23
#include "vorbiscomment.h"
24
24
#include "FLAC/assert.h"
25
25
#include "FLAC/metadata.h"
 
26
#include "share/grabbag.h" /* for grabbag__file_get_filesize() */
26
27
#include "share/utf8.h"
27
28
#include <ctype.h>
28
29
#include <stdio.h>
32
33
 
33
34
/*
34
35
 * This struct and the following 4 static functions are copied from
35
 
 * ../metaflac/main.c.  Maybe someday there will be a convenience
 
36
 * ../metaflac/.  Maybe someday there will be a convenience
36
37
 * library for Vorbis comment parsing.
37
38
 */
38
39
typedef struct {
41
42
        /* according to the vorbis spec, field values can contain \0 so simple C strings are not enough here */
42
43
        unsigned field_value_length;
43
44
        char *field_value;
 
45
        FLAC__bool field_value_from_file; /* true if field_value holds a filename for the value, false for plain value */
44
46
} Argument_VcField;
45
47
 
46
48
static void die(const char *message)
101
103
{
102
104
        FLAC__StreamMetadata_VorbisComment_Entry entry;
103
105
        char *converted;
104
 
        FLAC__bool needs_free = false;
105
106
 
106
107
        FLAC__ASSERT(0 != block);
107
108
        FLAC__ASSERT(block->type == FLAC__METADATA_TYPE_VORBIS_COMMENT);
108
109
        FLAC__ASSERT(0 != field);
109
110
        FLAC__ASSERT(0 != needs_write);
110
111
 
111
 
        if(raw) {
112
 
                entry.entry = (FLAC__byte *)field->field;
113
 
        }
114
 
        else if(utf8_encode(field->field, &converted) >= 0) {
115
 
                entry.entry = (FLAC__byte *)converted;
116
 
                needs_free = true;
117
 
        }
118
 
        else {
119
 
                *violation = "couldn't convert comment to UTF-8";
120
 
                return false;
121
 
        }
122
 
 
123
 
        entry.length = strlen((const char *)entry.entry);
124
 
 
125
 
        if(!FLAC__metadata_object_vorbiscomment_append_comment(block, entry, /*copy=*/true)) {
126
 
                if(needs_free)
 
112
        if(field->field_value_from_file) {
 
113
                /* read the file into 'data' */
 
114
                FILE *f = 0;
 
115
                char *data = 0;
 
116
                const off_t size = grabbag__file_get_filesize(field->field_value);
 
117
                if(size < 0) {
 
118
                        *violation = "can't open file for tag value";
 
119
                        return false;
 
120
                }
 
121
                if(size >= 0x100000) { /* magic arbitrary limit, actual format limit is near 16MB */
 
122
                        *violation = "file for tag value is too large";
 
123
                        return false;
 
124
                }
 
125
                if(0 == (data = malloc(size+1)))
 
126
                        die("out of memory allocating tag value");
 
127
                data[size] = '\0';
 
128
                if(0 == (f = fopen(field->field_value, "rb")) || fread(data, 1, size, f) != (size_t)size) {
 
129
                        free(data);
 
130
                        if(f)
 
131
                                fclose(f);
 
132
                        *violation = "error while reading file for tag value";
 
133
                        return false;
 
134
                }
 
135
                fclose(f);
 
136
                if(strlen(data) != (size_t)size) {
 
137
                        free(data);
 
138
                        *violation = "file for tag value has embedded NULs";
 
139
                        return false;
 
140
                }
 
141
 
 
142
                /* move 'data' into 'converted', converting to UTF-8 if necessary */
 
143
                if(raw) {
 
144
                        converted = data;
 
145
                }
 
146
                else if(utf8_encode(data, &converted) >= 0) {
 
147
                        free(data);
 
148
                }
 
149
                else {
 
150
                        free(data);
 
151
                        *violation = "error converting file contents to UTF-8 for tag value";
 
152
                        return false;
 
153
                }
 
154
 
 
155
                /* create and entry and append it */
 
156
                if(!FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair(&entry, field->field_name, converted)) {
127
157
                        free(converted);
128
 
                *violation = "memory allocation failure";
129
 
                return false;
 
158
                        *violation = "file for tag value is not valid UTF-8";
 
159
                        return false;
 
160
                }
 
161
                free(converted);
 
162
                if(!FLAC__metadata_object_vorbiscomment_append_comment(block, entry, /*copy=*/false)) {
 
163
                        *violation = "memory allocation failure";
 
164
                        return false;
 
165
                }
 
166
 
 
167
                *needs_write = true;
 
168
                return true;
130
169
        }
131
170
        else {
 
171
                FLAC__bool needs_free = false;
 
172
                if(raw) {
 
173
                        entry.entry = (FLAC__byte *)field->field;
 
174
                }
 
175
                else if(utf8_encode(field->field, &converted) >= 0) {
 
176
                        entry.entry = (FLAC__byte *)converted;
 
177
                        needs_free = true;
 
178
                }
 
179
                else {
 
180
                        *violation = "error converting comment to UTF-8";
 
181
                        return false;
 
182
                }
 
183
                entry.length = strlen((const char *)entry.entry);
 
184
                if(!FLAC__format_vorbiscomment_entry_is_legal(entry.entry, entry.length)) {
 
185
                        if(needs_free)
 
186
                                free(converted);
 
187
                        /*
 
188
                         * our previous parsing has already established that the field
 
189
                         * name is OK, so it must be the field value
 
190
                         */
 
191
                        *violation = "tag value for is not valid UTF-8";
 
192
                        return false;
 
193
                }
 
194
 
 
195
                if(!FLAC__metadata_object_vorbiscomment_append_comment(block, entry, /*copy=*/true)) {
 
196
                        if(needs_free)
 
197
                                free(converted);
 
198
                        *violation = "memory allocation failure";
 
199
                        return false;
 
200
                }
 
201
 
132
202
                *needs_write = true;
133
203
                if(needs_free)
134
204
                        free(converted);
150
220
                free(obj->field_value);
151
221
}
152
222
 
153
 
FLAC__bool flac__vorbiscomment_add(FLAC__StreamMetadata *block, const char *comment, const char **violation)
 
223
FLAC__bool flac__vorbiscomment_add(FLAC__StreamMetadata *block, const char *comment, FLAC__bool value_from_file, const char **violation)
154
224
{
155
225
        Argument_VcField parsed;
156
226
        FLAC__bool dummy;
161
231
 
162
232
        memset(&parsed, 0, sizeof(parsed));
163
233
 
 
234
        parsed.field_value_from_file = value_from_file;
164
235
        if(!parse_vorbis_comment_field(comment, &(parsed.field), &(parsed.field_name), &(parsed.field_value), &(parsed.field_value_length), violation)) {
165
236
                free_field(&parsed);
166
237
                return false;