Exemple #1
0
int ff_ape_write_tag(AVFormatContext *s)
{
    AVDictionaryEntry *e = NULL;
    int64_t start, end;
    int size, count = 0;

    if (!s->pb->seekable)
        return 0;

    start = avio_tell(s->pb);

    // header
    avio_write(s->pb, "APETAGEX", 8);   // id
    avio_wl32 (s->pb, APE_TAG_VERSION); // version
    avio_wl32(s->pb, 0);                // reserve space for size
    avio_wl32(s->pb, 0);                // reserve space for tag count

    // flags
    avio_wl32(s->pb, APE_TAG_FLAG_CONTAINS_HEADER | APE_TAG_FLAG_CONTAINS_FOOTER |
                     APE_TAG_FLAG_IS_HEADER);
    ffio_fill(s->pb, 0, 8);             // reserved

    while ((e = av_dict_get(s->metadata, "", e, AV_DICT_IGNORE_SUFFIX))) {
        int val_len;

        if (!string_is_ascii(e->key)) {
            av_log(s, AV_LOG_WARNING, "Non ASCII keys are not allowed\n");
            continue;
        }

        val_len = strlen(e->value);
        avio_wl32(s->pb, val_len);            // value length
        avio_wl32(s->pb, 0);                  // item flags
        avio_put_str(s->pb, e->key);          // key
        avio_write(s->pb, e->value, val_len); // value
        count++;
    }

    size = avio_tell(s->pb) - start;

    // footer
    avio_write(s->pb, "APETAGEX", 8);   // id
    avio_wl32 (s->pb, APE_TAG_VERSION); // version
    avio_wl32(s->pb, size);             // size
    avio_wl32(s->pb, count);            // tag count

    // flags
    avio_wl32(s->pb, APE_TAG_FLAG_CONTAINS_HEADER | APE_TAG_FLAG_CONTAINS_FOOTER);
    ffio_fill(s->pb, 0, 8);             // reserved

    // update values in the header
    end = avio_tell(s->pb);
    avio_seek(s->pb, start + 12, SEEK_SET);
    avio_wl32(s->pb, size);
    avio_wl32(s->pb, count);
    avio_seek(s->pb, end, SEEK_SET);

    return 0;
}
Exemple #2
0
int ff_ape_write_tag(AVFormatContext *s)
{
    AVDictionaryEntry *e = NULL;
    int size, ret, count = 0;
    AVIOContext *dyn_bc = NULL;
    uint8_t *dyn_buf = NULL;

    if ((ret = avio_open_dyn_buf(&dyn_bc)) < 0)
        goto end;

    // flags
    avio_wl32(dyn_bc, APE_TAG_FLAG_CONTAINS_HEADER | APE_TAG_FLAG_CONTAINS_FOOTER |
                     APE_TAG_FLAG_IS_HEADER);
    ffio_fill(dyn_bc, 0, 8);             // reserved

    ff_standardize_creation_time(s);
    while ((e = av_dict_get(s->metadata, "", e, AV_DICT_IGNORE_SUFFIX))) {
        int val_len;

        if (!string_is_ascii(e->key)) {
            av_log(s, AV_LOG_WARNING, "Non ASCII keys are not allowed\n");
            continue;
        }

        val_len = strlen(e->value);
        avio_wl32(dyn_bc, val_len);            // value length
        avio_wl32(dyn_bc, 0);                  // item flags
        avio_put_str(dyn_bc, e->key);          // key
        avio_write(dyn_bc, e->value, val_len); // value
        count++;
    }
    if (!count)
        goto end;

    size = avio_close_dyn_buf(dyn_bc, &dyn_buf);
    if (size <= 0)
        goto end;
    size += 20;

    // header
    avio_write(s->pb, "APETAGEX", 8);   // id
    avio_wl32(s->pb, APE_TAG_VERSION);  // version
    avio_wl32(s->pb, size);
    avio_wl32(s->pb, count);

    avio_write(s->pb, dyn_buf, size - 20);

    // footer
    avio_write(s->pb, "APETAGEX", 8);   // id
    avio_wl32(s->pb, APE_TAG_VERSION);  // version
    avio_wl32(s->pb, size);             // size
    avio_wl32(s->pb, count);            // tag count

    // flags
    avio_wl32(s->pb, APE_TAG_FLAG_CONTAINS_HEADER | APE_TAG_FLAG_CONTAINS_FOOTER);
    ffio_fill(s->pb, 0, 8);             // reserved

end:
    if (dyn_bc && !dyn_buf)
        avio_close_dyn_buf(dyn_bc, &dyn_buf);
    av_freep(&dyn_buf);

    return ret;
}
Exemple #3
0
/*
 * Helper function for pgp_armor. Converts arrays of keys and values into
 * plain C arrays, and checks that they don't contain invalid characters.
 */
static int
parse_key_value_arrays(ArrayType *key_array, ArrayType *val_array,
					   char ***p_keys, char ***p_values)
{
	int			nkdims = ARR_NDIM(key_array);
	int			nvdims = ARR_NDIM(val_array);
	char	  **keys,
			  **values;
	Datum	   *key_datums,
			   *val_datums;
	bool	   *key_nulls,
			   *val_nulls;
	int			key_count,
				val_count;
	int			i;

	if (nkdims > 1 || nkdims != nvdims)
		ereport(ERROR,
				(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
				 errmsg("wrong number of array subscripts")));
	if (nkdims == 0)
		return 0;

	deconstruct_array(key_array,
					  TEXTOID, -1, false, 'i',
					  &key_datums, &key_nulls, &key_count);

	deconstruct_array(val_array,
					  TEXTOID, -1, false, 'i',
					  &val_datums, &val_nulls, &val_count);

	if (key_count != val_count)
		ereport(ERROR,
				(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
				 errmsg("mismatched array dimensions")));

	keys = (char **) palloc(sizeof(char *) * key_count);
	values = (char **) palloc(sizeof(char *) * val_count);

	for (i = 0; i < key_count; i++)
	{
		char	   *v;

		/* Check that the key doesn't contain anything funny */
		if (key_nulls[i])
			ereport(ERROR,
					(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
					 errmsg("null value not allowed for header key")));

		v = TextDatumGetCString(key_datums[i]);

		if (!string_is_ascii(v))
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				errmsg("header key must not contain non-ASCII characters")));
		if (strstr(v, ": "))
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
					 errmsg("header key must not contain \": \"")));
		if (strchr(v, '\n'))
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
					 errmsg("header key must not contain newlines")));
		keys[i] = v;

		/* And the same for the value */
		if (val_nulls[i])
			ereport(ERROR,
					(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
					 errmsg("null value not allowed for header value")));

		v = TextDatumGetCString(val_datums[i]);

		if (!string_is_ascii(v))
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
			  errmsg("header value must not contain non-ASCII characters")));
		if (strchr(v, '\n'))
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
					 errmsg("header value must not contain newlines")));

		values[i] = v;
	}

	*p_keys = keys;
	*p_values = values;
	return key_count;
}