general status code enum

This commit is contained in:
Frédéric Mangano-Tarumi 2018-11-09 18:28:21 -05:00
parent 72a911c11b
commit 0c4c11032f
4 changed files with 45 additions and 40 deletions

View File

@ -34,41 +34,41 @@
#define le32toh(x) OSSwapLittleToHostInt32(x)
#endif
ot::parse_result ot::parse_tags(const char *data, long len, opus_tags *tags)
ot::status ot::parse_tags(const char *data, long len, opus_tags *tags)
{
long pos;
if (8 > len)
return parse_result::overflowing_magic_number;
return status::overflowing_magic_number;
if (memcmp(data, "OpusTags", 8) != 0)
return parse_result::bad_magic_number;
return status::bad_magic_number;
// Vendor
pos = 8;
if (pos + 4 > len)
return parse_result::overflowing_vendor_length;
return status::overflowing_vendor_length;
size_t vendor_length = le32toh(*((uint32_t*) (data + pos)));
if (pos + 4 + vendor_length > len)
return parse_result::overflowing_vendor_data;
return status::overflowing_vendor_data;
tags->vendor = ot::string_view(data + pos + 4, vendor_length);
pos += 4 + tags->vendor.size();
// Count
if (pos + 4 > len)
return parse_result::overflowing_comment_count;
return status::overflowing_comment_count;
uint32_t count = le32toh(*((uint32_t*) (data + pos)));
pos += 4;
// Comments
for (uint32_t i = 0; i < count; ++i) {
if (pos + 4 > len)
return parse_result::overflowing_comment_length;
return status::overflowing_comment_length;
uint32_t comment_length = le32toh(*((uint32_t*) (data + pos)));
if (pos + 4 + comment_length > len)
return parse_result::overflowing_comment_data;
return status::overflowing_comment_data;
const char *comment_value = data + pos + 4;
tags->comments.emplace_back(comment_value, comment_length);
pos += 4 + comment_length;
}
// Extra data
tags->extra_data = ot::string_view(data + pos, static_cast<size_t>(len - pos));
return parse_result::ok;
return status::ok;
}
int ot::render_tags(opus_tags *tags, ogg_packet *op)

View File

@ -252,7 +252,7 @@ int main(int argc, char **argv){
}
}
else if(packet_count == 2){ // Comment header
if(ot::parse_tags((char*) reader.packet.packet, reader.packet.bytes, &tags) != ot::parse_result::ok){
if(ot::parse_tags((char*) reader.packet.packet, reader.packet.bytes, &tags) != ot::status::ok){
error = "opustags: invalid comment header";
break;
}

View File

@ -34,6 +34,30 @@ private:
size_t _size = 0;
};
/**
* Possible error status.
*
* The overflowing error family means that the end of packet was reached when
* attempting to read the overflowing value. For example,
* overflowing_comment_count means that after reading the vendor string, less
* than 4 bytes were left in the packet.
*/
enum class status {
ok,
/** On standard error, errno will give more details. */
standard_error,
end_of_file,
libogg_error,
/* OpusTags parsing errors */
bad_magic_number,
overflowing_magic_number,
overflowing_vendor_length,
overflowing_vendor_data,
overflowing_comment_count,
overflowing_comment_length,
overflowing_comment_data,
};
/**
* \defgroup ogg Ogg
* \brief Helpers to work with libogg.
@ -164,26 +188,7 @@ struct opus_tags {
string_view extra_data;
};
/**
* Possible return status of #parse_tags.
*
* The overflowing error family means that the end of packet was reached when
* attempting to read the overflowing value. For example,
* overflowing_comment_count means that after reading the vendor string, less
* than 4 bytes were left in the packet.
*/
enum class parse_result {
ok = 0,
bad_magic_number = -100,
overflowing_magic_number,
overflowing_vendor_length,
overflowing_vendor_data,
overflowing_comment_count,
overflowing_comment_length,
overflowing_comment_data,
};
parse_result parse_tags(const char *data, long len, opus_tags *tags);
status parse_tags(const char *data, long len, opus_tags *tags);
int render_tags(opus_tags *tags, ogg_packet *op);
void delete_tags(opus_tags *tags, const char *field);

View File

@ -40,7 +40,7 @@ static bool parse_standard()
{
ot::opus_tags tags;
auto rc = ot::parse_tags(standard_OpusTags, sizeof(standard_OpusTags) - 1, &tags);
if (rc != ot::parse_result::ok)
if (rc != ot::status::ok)
throw failure("ot::parse_tags did not return ok");
if (tags.vendor != ot::string_view( "opustags test packet"))
throw failure("bad vendor string");
@ -77,29 +77,29 @@ static bool parse_corrupted()
char* first_comment_data = first_comment_length + 4;
char* end = packet + size;
if (ot::parse_tags(packet, 7, &tags) != ot::parse_result::overflowing_magic_number)
if (ot::parse_tags(packet, 7, &tags) != ot::status::overflowing_magic_number)
throw failure("did not detect the overflowing magic number");
if (ot::parse_tags(packet, 11, &tags) != ot::parse_result::overflowing_vendor_length)
if (ot::parse_tags(packet, 11, &tags) != ot::status::overflowing_vendor_length)
throw failure("did not detect the overflowing vendor string length");
header_data[0] = 'o';
if (ot::parse_tags(packet, size, &tags) != ot::parse_result::bad_magic_number)
if (ot::parse_tags(packet, size, &tags) != ot::status::bad_magic_number)
throw failure("did not detect the bad magic number");
header_data[0] = 'O';
*vendor_length = end - vendor_string + 1;
if (ot::parse_tags(packet, size, &tags) != ot::parse_result::overflowing_vendor_data)
if (ot::parse_tags(packet, size, &tags) != ot::status::overflowing_vendor_data)
throw failure("did not detect the overflowing vendor string");
*vendor_length = end - vendor_string - 3;
if (ot::parse_tags(packet, size, &tags) != ot::parse_result::overflowing_comment_count)
if (ot::parse_tags(packet, size, &tags) != ot::status::overflowing_comment_count)
throw failure("did not detect the overflowing comment count");
*vendor_length = comment_count - vendor_string;
++*comment_count;
if (ot::parse_tags(packet, size, &tags) != ot::parse_result::overflowing_comment_length)
if (ot::parse_tags(packet, size, &tags) != ot::status::overflowing_comment_length)
throw failure("did not detect the overflowing comment length");
*first_comment_length = end - first_comment_data + 1;
if (ot::parse_tags(packet, size, &tags) != ot::parse_result::overflowing_comment_data)
if (ot::parse_tags(packet, size, &tags) != ot::status::overflowing_comment_data)
throw failure("did not detect the overflowing comment data");
return true;
@ -109,7 +109,7 @@ static bool recode_standard()
{
ot::opus_tags tags;
auto rc = ot::parse_tags(standard_OpusTags, sizeof(standard_OpusTags) - 1, &tags);
if (rc != ot::parse_result::ok)
if (rc != ot::status::ok)
throw failure("ot::parse_tags did not return ok");
ogg_packet packet;
if (ot::render_tags(&tags, &packet) != 0)
@ -137,7 +137,7 @@ static bool recode_padding()
// ^ note: padded_OpusTags ends with a null byte here
padded_OpusTags += "hello";
auto rc = ot::parse_tags(padded_OpusTags.data(), padded_OpusTags.size(), &tags);
if (rc != ot::parse_result::ok)
if (rc != ot::status::ok)
throw failure("ot::parse_tags did not return ok");
if (tags.extra_data != ot::string_view("\0hello", 6))
throw failure("corrupted extra data");