diff --git a/src/metaflac/operations_shorthand_vorbiscomment.c b/src/metaflac/operations_shorthand_vorbiscomment.c index 95e2bf38ed..4a0a8faa8e 100644 --- a/src/metaflac/operations_shorthand_vorbiscomment.c +++ b/src/metaflac/operations_shorthand_vorbiscomment.c @@ -359,33 +359,39 @@ FLAC__bool import_vc_from(const char *filename, FLAC__StreamMetadata *block, con ret = true; while(ret && !feof(f) && fgets(line, sizeof(line), f) != NULL) { - if(!feof(f)) { - char *p = strchr(line, '\n'); - if(0 == p) { + char *p = strpbrk(line, "\r\n"); + if(0 == p) { + const size_t len = strlen(line); + if(len < (sizeof(line) - 1)) { + /* Likely missing newline in the last line, allow this */ + p = &line[len]; + } + else { flac_fprintf(stderr, "%s: ERROR: line too long, aborting\n", vc_filename->value); ret = false; } + } + + if(ret) { + const char *violation; + Argument_VcField field; + *p = '\0'; + memset(&field, 0, sizeof(Argument_VcField)); + field.field_value_from_file = false; + if(!parse_vorbis_comment_field(line, &field.field, &field.field_name, &field.field_value, &field.field_value_length, &violation)) { + FLAC__ASSERT(0 != violation); + flac_fprintf(stderr, "%s: ERROR: malformed vorbis comment field \"%s\",\n %s\n", vc_filename->value, line, violation); + ret = false; + } else { - const char *violation; - Argument_VcField field; - *p = '\0'; - memset(&field, 0, sizeof(Argument_VcField)); - field.field_value_from_file = false; - if(!parse_vorbis_comment_field(line, &field.field, &field.field_name, &field.field_value, &field.field_value_length, &violation)) { - FLAC__ASSERT(0 != violation); - flac_fprintf(stderr, "%s: ERROR: malformed vorbis comment field \"%s\",\n %s\n", vc_filename->value, line, violation); - ret = false; - } - else { - ret = set_vc_field(filename, block, &field, needs_write, raw); - } - if(0 != field.field) - free(field.field); - if(0 != field.field_name) - free(field.field_name); - if(0 != field.field_value) - free(field.field_value); + ret = set_vc_field(filename, block, &field, needs_write, raw); } + if(0 != field.field) + free(field.field); + if(0 != field.field_name) + free(field.field_name); + if(0 != field.field_value) + free(field.field_value); } }; diff --git a/test/test_metaflac.sh b/test/test_metaflac.sh index 0cfbac6b7d..e4893b78e4 100755 --- a/test/test_metaflac.sh +++ b/test/test_metaflac.sh @@ -120,7 +120,23 @@ metaflac_test () run_metaflac $args $flacfile | filter > $testdir/out1.meta || die "ERROR running metaflac" # Ignore lengths which can be affected by the version string. sed "s/length:.*/length: XXX/" $testdir/out1.meta > $testdir/out.meta - diff -w $expect $testdir/out.meta > /dev/null 2>&1 || die "ERROR: metadata does not match expected $expect" + exit_code=0 + diff -w $expect $testdir/out.meta > /dev/null 2>&1 || exit_code=$? + if [ "$exit_code" != 0 ] ; then + echo "" + echo "diff of expected and actual metadata:" + diff -w $expect $testdir/out.meta || true + + # Also output a hexdump of the metadata, which can be useful in case there are in fact + # differences in whitespace + echo "" + echo "hexdump diff of expected and actual metadata:" + hd "$expect" > "$testdir/out.meta.expect.hd" || true + hd "$testdir/out.meta" > "$testdir/out.meta.hd" || true + diff "$testdir/out.meta.expect.hd" "$testdir/out.meta.hd" || true + + die "ERROR: metadata does not match expected $expect" + fi # To blindly accept (and check later): cp -f $testdir/out.meta $expect echo OK } @@ -354,6 +370,18 @@ echo "TITLE=Tittle" | run_metaflac --import-tags-from=- $flacfile check_flac metaflac_test case39 "--import-tags-from=-" "--list" +# Run same test again, but with \r\n newline: +run_metaflac --remove-all-tags --set-tag="f=0123456789abcdefghij" $flacfile +printf 'TITLE=Tittle\r\n' | run_metaflac --import-tags-from=- $flacfile +check_flac +metaflac_test case39 "--import-tags-from=-" "--list" + +# Run same test again, but without newline at the end: +run_metaflac --remove-all-tags --set-tag="f=0123456789abcdefghij" $flacfile +echo $ECHO_N "TITLE=Tittle" | run_metaflac --import-tags-from=- $flacfile +check_flac +metaflac_test case39 "--import-tags-from=-" "--list" + cat > vc.txt << EOF artist=Fartist artist=artits @@ -362,6 +390,20 @@ run_metaflac --import-tags-from=vc.txt $flacfile check_flac metaflac_test case40 "--import-tags-from=[FILE]" "--list" +# Run same test again, but with \r\n newlines: +printf 'artist=Fartist\r\nartist=artits\r\n' >vc.txt +run_metaflac --remove-all-tags --set-tag="f=0123456789abcdefghij" --set-tag="TITLE=Tittle" $flacfile +run_metaflac --import-tags-from=vc.txt $flacfile +check_flac +metaflac_test case40 "--import-tags-from=[FILE]" "--list" + +# Run same test again, but without newline at the end: +printf 'artist=Fartist\nartist=artits' >vc.txt +run_metaflac --remove-all-tags --set-tag="f=0123456789abcdefghij" --set-tag="TITLE=Tittle" $flacfile +run_metaflac --import-tags-from=vc.txt $flacfile +check_flac +metaflac_test case40 "--import-tags-from=[FILE]" "--list" + rm vc.txt run_metaflac --add-replay-gain $flacfile