error when --set-all's parsing fails

This commit is contained in:
Frédéric Mangano-Tarumi 2018-12-16 12:50:18 -05:00
parent 46cd25f744
commit e26f3f268c
4 changed files with 44 additions and 33 deletions

View File

@ -176,14 +176,10 @@ void ot::print_comments(const std::list<std::string>& comments, FILE* output)
fputs("warning: Some tags contain control characters.\n", stderr);
}
/**
* \todo Report errors to the caller, so the program exits with a failure instead of skipping tags.
* This could wait until we throw ot::status instead of returning them.
*/
std::list<std::string> ot::read_comments(FILE* input)
ot::status ot::read_comments(FILE* input, std::list<std::string>& comments)
{
static ot::encoding_converter to_utf8("", "UTF-8");
std::list<std::string> comments;
comments.clear();
char* line = nullptr;
size_t buflen = 0;
ssize_t nread;
@ -193,29 +189,33 @@ std::list<std::string> ot::read_comments(FILE* input)
if (nread == 0)
continue;
if (memchr(line, '=', nread) == nullptr) {
fputs("warning: skipping malformed tag\n", stderr);
continue;
ot::status rc = {ot::st::error, "Malformed tag: " + std::string(line, nread)};
free(line);
return rc;
}
std::string utf8;
ot::status rc = to_utf8(line, nread, utf8);
if (rc == ot::st::ok)
comments.emplace_back(std::move(utf8));
else
fprintf(stderr, "warning: Skipping tag with UTF-8 conversion error: %s\n", rc.message.c_str());
return {ot::st::badly_encoded, "UTF-8 conversion error: " + rc.message};
}
free(line);
return comments;
return ot::st::ok;
}
/** Apply the modifications requested by the user to the opustags packet. */
static ot::status edit_tags(ot::opus_tags& tags, const ot::options& opt)
{
if (opt.set_all)
tags.comments = ot::read_comments(stdin);
else if (opt.delete_all)
if (opt.set_all) {
auto rc = ot::read_comments(stdin, tags.comments);
if (rc != ot::st::ok)
return rc;
} else if (opt.delete_all) {
tags.comments.clear();
else for (const std::string& name : opt.to_delete)
} else for (const std::string& name : opt.to_delete) {
ot::delete_comments(tags, name.c_str());
}
for (const std::string& comment : opt.to_add)
tags.comments.emplace_back(comment);

View File

@ -466,7 +466,7 @@ void print_comments(const std::list<std::string>& comments, FILE* output);
*
* The comments are converted from the system encoding to UTF-8, and returned as UTF-8.
*/
std::list<std::string> read_comments(FILE* input);
status read_comments(FILE* input, std::list<std::string>& comments);
/**
* Main entry point to the opustags program, and pretty much the same as calling opustags from the

View File

@ -3,19 +3,36 @@
#include <string.h>
const char *user_comments = R"raw(
TITLE=a b c
ARTIST=X
Artist=Y)raw";
using namespace std::literals::string_literals;
void check_read_comments()
{
ot::file input = fmemopen(const_cast<char*>(user_comments), strlen(user_comments), "r");
auto comments = ot::read_comments(input.get());
auto&& expected = {"TITLE=a b c", "ARTIST=X", "Artist=Y"};
if (!std::equal(comments.begin(), comments.end(), expected.begin(), expected.end()))
throw failure("parsed user comments did not match expectations");
std::list<std::string> comments;
ot::status rc;
{
std::string txt = "TITLE=a b c\n\nARTIST=X\nArtist=Y\n"s;
ot::file input = fmemopen((char*) txt.data(), txt.size(), "r");
rc = ot::read_comments(input.get(), comments);
if (rc != ot::st::ok)
throw failure("could not read comments");
auto&& expected = {"TITLE=a b c", "ARTIST=X", "Artist=Y"};
if (!std::equal(comments.begin(), comments.end(), expected.begin(), expected.end()))
throw failure("parsed user comments did not match expectations");
}
{
std::string txt = "CORRUPTED=\xFF\xFF\n"s;
ot::file input = fmemopen((char*) txt.data(), txt.size(), "r");
rc = ot::read_comments(input.get(), comments);
if (rc != ot::st::badly_encoded)
throw failure("did not get the expected error reading corrupted data");
}
{
std::string txt = "MALFORMED\n"s;
ot::file input = fmemopen((char*) txt.data(), txt.size(), "r");
rc = ot::read_comments(input.get(), comments);
if (rc != ot::st::error)
throw failure("did not get the expected error reading malformed comments");
}
}
void check_good_arguments()

View File

@ -175,18 +175,12 @@ A=B
X=Z
END_OUT
is_deeply(opustags(qw(out.opus -S), {in => <<'END_IN'}), [<<'END_OUT', <<'END_ERR', 0], 'set all with bad tags');
is_deeply(opustags(qw(out.opus -S), {in => <<'END_IN'}), [<<'END_OUT', <<'END_ERR', 256], 'set all with bad tags');
whatever
# thing
!
wrong=yes
END_IN
wrong=yes
END_OUT
warning: skipping malformed tag
warning: skipping malformed tag
warning: skipping malformed tag
error: Malformed tag: whatever
END_ERR
sub slurp {