Upstream-Status: Backport [http://lame.cvs.sourceforge.net/viewvc/lame/lame/libmp3lame/id3tag.c?r1=1.79&r2=1.80] Backport patch to fix CVE-2017-13712 for lame. Signed-off-by: Kai Kang Signed-off-by: Stefan Agner --- --- a/libmp3lame/id3tag.c (revision 6426) +++ b/libmp3lame/id3tag.c (working copy) @@ -195,8 +195,12 @@ } #endif +static int +is_lame_internal_flags_null(lame_t gfp) +{ + return (gfp && gfp->internal_flags) ? 0 : 1; +} - static int id3v2_add_ucs2(lame_t gfp, uint32_t frame_id, char const *lang, unsigned short const *desc, unsigned short const *text); static int @@ -238,8 +242,7 @@ static void id3v2AddAudioDuration(lame_t gfp, double ms) { - lame_internal_flags *gfc = gfp != 0 ? gfp->internal_flags : 0; - SessionConfig_t const *const cfg = &gfc->cfg; + SessionConfig_t const *const cfg = &gfp->internal_flags->cfg; /* caller checked pointers */ char buffer[1024]; double const max_ulong = MAX_U_32_NUM; unsigned long playlength_ms; @@ -280,7 +283,12 @@ void id3tag_init(lame_t gfp) { - lame_internal_flags *gfc = gfp->internal_flags; + lame_internal_flags *gfc = 0; + + if (is_lame_internal_flags_null(gfp)) { + return; + } + gfc = gfp->internal_flags; free_id3tag(gfc); memset(&gfc->tag_spec, 0, sizeof gfc->tag_spec); gfc->tag_spec.genre_id3v1 = GENRE_NUM_UNKNOWN; @@ -293,7 +301,12 @@ void id3tag_add_v2(lame_t gfp) { - lame_internal_flags *gfc = gfp->internal_flags; + lame_internal_flags *gfc = 0; + + if (is_lame_internal_flags_null(gfp)) { + return; + } + gfc = gfp->internal_flags; gfc->tag_spec.flags &= ~V1_ONLY_FLAG; gfc->tag_spec.flags |= ADD_V2_FLAG; } @@ -301,7 +314,12 @@ void id3tag_v1_only(lame_t gfp) { - lame_internal_flags *gfc = gfp->internal_flags; + lame_internal_flags *gfc = 0; + + if (is_lame_internal_flags_null(gfp)) { + return; + } + gfc = gfp->internal_flags; gfc->tag_spec.flags &= ~(ADD_V2_FLAG | V2_ONLY_FLAG); gfc->tag_spec.flags |= V1_ONLY_FLAG; } @@ -309,7 +327,12 @@ void id3tag_v2_only(lame_t gfp) { - lame_internal_flags *gfc = gfp->internal_flags; + lame_internal_flags *gfc = 0; + + if (is_lame_internal_flags_null(gfp)) { + return; + } + gfc = gfp->internal_flags; gfc->tag_spec.flags &= ~V1_ONLY_FLAG; gfc->tag_spec.flags |= V2_ONLY_FLAG; } @@ -317,7 +340,12 @@ void id3tag_space_v1(lame_t gfp) { - lame_internal_flags *gfc = gfp->internal_flags; + lame_internal_flags *gfc = 0; + + if (is_lame_internal_flags_null(gfp)) { + return; + } + gfc = gfp->internal_flags; gfc->tag_spec.flags &= ~V2_ONLY_FLAG; gfc->tag_spec.flags |= SPACE_V1_FLAG; } @@ -331,7 +359,12 @@ void id3tag_set_pad(lame_t gfp, size_t n) { - lame_internal_flags *gfc = gfp->internal_flags; + lame_internal_flags *gfc = 0; + + if (is_lame_internal_flags_null(gfp)) { + return; + } + gfc = gfp->internal_flags; gfc->tag_spec.flags &= ~V1_ONLY_FLAG; gfc->tag_spec.flags |= PAD_V2_FLAG; gfc->tag_spec.flags |= ADD_V2_FLAG; @@ -583,23 +616,30 @@ int id3tag_set_albumart(lame_t gfp, const char *image, size_t size) { - int mimetype = 0; - unsigned char const *data = (unsigned char const *) image; - lame_internal_flags *gfc = gfp->internal_flags; + int mimetype = MIMETYPE_NONE; + lame_internal_flags *gfc = 0; - /* determine MIME type from the actual image data */ - if (2 < size && data[0] == 0xFF && data[1] == 0xD8) { - mimetype = MIMETYPE_JPEG; + if (is_lame_internal_flags_null(gfp)) { + return 0; } - else if (4 < size && data[0] == 0x89 && strncmp((const char *) &data[1], "PNG", 3) == 0) { - mimetype = MIMETYPE_PNG; + gfc = gfp->internal_flags; + + if (image != 0) { + unsigned char const *data = (unsigned char const *) image; + /* determine MIME type from the actual image data */ + if (2 < size && data[0] == 0xFF && data[1] == 0xD8) { + mimetype = MIMETYPE_JPEG; + } + else if (4 < size && data[0] == 0x89 && strncmp((const char *) &data[1], "PNG", 3) == 0) { + mimetype = MIMETYPE_PNG; + } + else if (4 < size && strncmp((const char *) data, "GIF8", 4) == 0) { + mimetype = MIMETYPE_GIF; + } + else { + return -1; + } } - else if (4 < size && strncmp((const char *) data, "GIF8", 4) == 0) { - mimetype = MIMETYPE_GIF; - } - else { - return -1; - } if (gfc->tag_spec.albumart != 0) { free(gfc->tag_spec.albumart); gfc->tag_spec.albumart = 0; @@ -606,7 +646,7 @@ gfc->tag_spec.albumart_size = 0; gfc->tag_spec.albumart_mimetype = MIMETYPE_NONE; } - if (size < 1) { + if (size < 1 || mimetype == MIMETYPE_NONE) { return 0; } gfc->tag_spec.albumart = lame_calloc(unsigned char, size); @@ -934,6 +974,9 @@ if (frame_id == 0) { return -1; } + if (is_lame_internal_flags_null(gfp)) { + return 0; + } if (text == 0) { return 0; } @@ -983,6 +1026,9 @@ if (frame_id == 0) { return -1; } + if (is_lame_internal_flags_null(gfp)) { + return 0; + } if (text == 0) { return 0; } @@ -1012,6 +1058,9 @@ int id3tag_set_comment_latin1(lame_t gfp, char const *lang, char const *desc, char const *text) { + if (is_lame_internal_flags_null(gfp)) { + return 0; + } return id3v2_add_latin1(gfp, ID_COMMENT, lang, desc, text); } @@ -1019,6 +1068,9 @@ int id3tag_set_comment_utf16(lame_t gfp, char const *lang, unsigned short const *desc, unsigned short const *text) { + if (is_lame_internal_flags_null(gfp)) { + return 0; + } return id3v2_add_ucs2(gfp, ID_COMMENT, lang, desc, text); } @@ -1029,6 +1081,9 @@ int id3tag_set_comment_ucs2(lame_t gfp, char const *lang, unsigned short const *desc, unsigned short const *text) { + if (is_lame_internal_flags_null(gfp)) { + return 0; + } return id3tag_set_comment_utf16(gfp, lang, desc, text); } @@ -1219,9 +1274,9 @@ int id3tag_set_genre(lame_t gfp, const char *genre) { - lame_internal_flags *gfc = gfp->internal_flags; + lame_internal_flags *gfc = gfp != 0 ? gfp->internal_flags : 0; int ret = 0; - if (genre && *genre) { + if (gfc && genre && *genre) { int const num = lookupGenre(genre); if (num == -1) return num; gfc->tag_spec.flags |= CHANGED_FLAG; @@ -1514,6 +1569,9 @@ int id3tag_set_fieldvalue(lame_t gfp, const char *fieldvalue) { + if (is_lame_internal_flags_null(gfp)) { + return 0; + } if (fieldvalue && *fieldvalue) { if (strlen(fieldvalue) < 5 || fieldvalue[4] != '=') { return -1; @@ -1526,6 +1584,9 @@ int id3tag_set_fieldvalue_utf16(lame_t gfp, const unsigned short *fieldvalue) { + if (is_lame_internal_flags_null(gfp)) { + return 0; + } if (fieldvalue && *fieldvalue) { size_t dx = hasUcs2ByteOrderMarker(fieldvalue[0]); unsigned short const separator = fromLatin1Char(fieldvalue, '='); @@ -1556,6 +1617,9 @@ int id3tag_set_fieldvalue_ucs2(lame_t gfp, const unsigned short *fieldvalue) { + if (is_lame_internal_flags_null(gfp)) { + return 0; + } return id3tag_set_fieldvalue_utf16(gfp, fieldvalue); } @@ -1562,14 +1626,12 @@ size_t lame_get_id3v2_tag(lame_t gfp, unsigned char *buffer, size_t size) { - lame_internal_flags *gfc; - if (gfp == 0) { + lame_internal_flags *gfc = 0; + + if (is_lame_internal_flags_null(gfp)) { return 0; } gfc = gfp->internal_flags; - if (gfc == 0) { - return 0; - } if (test_tag_spec_flags(gfc, V1_ONLY_FLAG)) { return 0; } @@ -1711,7 +1773,12 @@ int id3tag_write_v2(lame_t gfp) { - lame_internal_flags *gfc = gfp->internal_flags; + lame_internal_flags *gfc = 0; + + if (is_lame_internal_flags_null(gfp)) { + return 0; + } + gfc = gfp->internal_flags; #if 0 debug_tag_spec_flags(gfc, "write v2"); #endif @@ -1812,10 +1879,15 @@ int id3tag_write_v1(lame_t gfp) { - lame_internal_flags *const gfc = gfp->internal_flags; + lame_internal_flags* gfc = 0; size_t i, n, m; unsigned char tag[128]; + if (is_lame_internal_flags_null(gfp)) { + return 0; + } + gfc = gfp->internal_flags; + m = sizeof(tag); n = lame_get_id3v1_tag(gfp, tag, m); if (n > m) {