clean up xml parsing, fix numbers xlsx decryption, unskip some tests

This commit is contained in:
Thomas Fussell 2016-11-25 13:13:55 +00:00
parent 6653568a1c
commit 2cc3f7947a
11 changed files with 746 additions and 870 deletions

View File

@ -24,6 +24,7 @@
#include <detail/constants.hpp>
#include <xlnt/xlnt_config.hpp>
#include <xlnt/utils/exceptions.hpp>
namespace xlnt {
@ -69,7 +70,7 @@ const std::unordered_map<std::string, std::string> &constants::get_namespaces()
static const std::unordered_map<std::string, std::string> *namespaces =
new std::unordered_map<std::string, std::string>
{
{ "worksheet", "http://schemas.openxmlformats.org/spreadsheetml/2006/main" },
{ "spreadsheetml", "http://schemas.openxmlformats.org/spreadsheetml/2006/main" },
{ "content-types", "http://schemas.openxmlformats.org/package/2006/content-types" },
{ "relationships", "http://schemas.openxmlformats.org/package/2006/relationships" },
{ "drawingml", "http://schemas.openxmlformats.org/drawingml/2006/main" },
@ -102,7 +103,14 @@ const std::unordered_map<std::string, std::string> &constants::get_namespaces()
const std::string &constants::get_namespace(const std::string &id)
{
return get_namespaces().find(id)->second;
auto match = get_namespaces().find(id);
if (match == get_namespaces().end())
{
throw xlnt::exception("bad namespace");
}
return match->second;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -35,6 +35,7 @@
namespace xlnt {
class formatted_text;
class path;
class relationship;
class workbook;
@ -220,13 +221,31 @@ private:
/// </summary>
void read_unknown_relationships();
std::vector<relationship> read_relationships(const path &part);
std::string read_text();
void read_block(const std::unordered_map<xml::qname, std::function<void(xlsx_consumer &)>> &handlers);
formatted_text read_formatted_text(const std::string &xmlns);
void read_part(const std::vector<relationship> &rel_chain);
void skip_attribute(const std::string &name);
void skip_attributes();
void skip_attributes(const std::vector<xml::qname> &names);
void skip_attributes(const std::vector<std::string> &names);
void skip_remaining_content(const xml::qname &name);
xml::qname expect_start_element(xml::content content);
void expect_start_element(const xml::qname &name, xml::content content);
void expect_end_element(const xml::qname &name);
bool in_element(const xml::qname &name);
std::vector<std::string> read_namespaces();
/// <summary>
/// The ZIP file containing the files that make up the OOXML package.
@ -255,6 +274,8 @@ private:
/// to access the object.
/// </summary>
xml::parser *parser_;
std::vector<xml::qname> stack_;
};
} // namespace detail

View File

@ -586,6 +586,7 @@ struct crypto_helper
= { {0xd7, 0xaa, 0x0f, 0x6d, 0x30, 0x61, 0x34, 0x4e} };
auto expected_verifier = calculate_block(h_n, verifier_block_key,
result.key_encryptor.verifier_hash_value);
expected_verifier.resize(calculated_verifier.size());
if (calculated_verifier.size() != expected_verifier.size()
|| std::mismatch(calculated_verifier.begin(), calculated_verifier.end(),

View File

@ -352,7 +352,7 @@ void xlsx_producer::write_workbook(const relationship &rel)
static const auto &xmlns_mc = constants::get_namespace("mc");
static const auto &xmlns_mx = constants::get_namespace("mx");
static const auto &xmlns_r = constants::get_namespace("r");
static const auto &xmlns_s = constants::get_namespace("worksheet");
static const auto &xmlns_s = constants::get_namespace("spreadsheetml");
static const auto &xmlns_x15 = constants::get_namespace("x15");
static const auto &xmlns_x15ac = constants::get_namespace("x15ac");
@ -671,7 +671,7 @@ void xlsx_producer::write_pivot_table(const relationship &/*rel*/)
void xlsx_producer::write_shared_string_table(const relationship &/*rel*/)
{
static const auto &xmlns = constants::get_namespace("worksheet");
static const auto &xmlns = constants::get_namespace("spreadsheetml");
serializer().start_element(xmlns, "sst");
serializer().namespace_decl(xmlns, "");
@ -796,7 +796,7 @@ void xlsx_producer::write_shared_workbook_user_data(const relationship &/*rel*/)
void xlsx_producer::write_styles(const relationship &/*rel*/)
{
static const auto &xmlns = constants::get_namespace("worksheet");
static const auto &xmlns = constants::get_namespace("spreadsheetml");
static const auto &xmlns_mc = constants::get_namespace("mc");
static const auto &xmlns_x14 = constants::get_namespace("x14");
static const auto &xmlns_x14ac = constants::get_namespace("x14ac");
@ -1830,7 +1830,7 @@ void xlsx_producer::write_volatile_dependencies(const relationship &/*rel*/)
void xlsx_producer::write_worksheet(const relationship &rel)
{
static const auto &xmlns = constants::get_namespace("worksheet");
static const auto &xmlns = constants::get_namespace("spreadsheetml");
static const auto &xmlns_r = constants::get_namespace("r");
static const auto &xmlns_mc = constants::get_namespace("mc");
static const auto &xmlns_x14ac = constants::get_namespace("x14ac");
@ -2400,7 +2400,7 @@ void xlsx_producer::write_worksheet(const relationship &rel)
void xlsx_producer::write_comments(const relationship &/*rel*/, worksheet ws,
const std::vector<cell_reference> &cells)
{
static const auto &xmlns = constants::get_namespace("worksheet");
static const auto &xmlns = constants::get_namespace("spreadsheetml");
serializer().start_element(xmlns, "comments");
serializer().namespace_decl(xmlns, "");

View File

@ -7,6 +7,8 @@
#include <helpers/path_helper.hpp>
#include <xlnt/workbook/workbook.hpp>
// Cryptographic key generation can take a few seconds, particularly in unoptomized builds.
// Set this to false to skip those tests that use cryptography.
#define TEST_CRYPTO true
#ifndef TEST_CRYPTO
@ -42,7 +44,6 @@ public:
void test_decrypt_numbers()
{
TS_SKIP("");
xlnt::workbook wb;
#if TEST_CRYPTO
wb.load(path_helper::get_data_directory("17_encrypted_numbers.xlsx"), "secret");

View File

@ -43,7 +43,6 @@ public:
void test_produce_default_libre_office()
{
TS_SKIP("");
xlnt::workbook wb = xlnt::workbook::empty_libre_office();
TS_ASSERT(workbook_matches_file(wb, path_helper::get_data_directory("10_default-libre-office.xlsx")));
}
@ -185,6 +184,6 @@ public:
wb.save("debug.xlsx");
//TS_ASSERT(workbook_matches_file(wb, xlnt::path("data/18_basic_comments.xlsx")));
TS_ASSERT(workbook_matches_file(wb, xlnt::path("data/18_basic_comments.xlsx")));
}
};

View File

@ -70,12 +70,11 @@ public:
void test_round_trip_empty_libre_office_wrw()
{
TS_SKIP("");
xlnt::workbook wb = xlnt::workbook::empty_libre_office();
TS_ASSERT(round_trip_matches_wrw(wb));
}
void test_round_trip_empty_pages_wrw()
void test_round_trip_empty_numbers_wrw()
{
TS_SKIP("");
xlnt::workbook wb = xlnt::workbook::empty_numbers();
@ -96,11 +95,17 @@ public:
void test_round_trip_empty_libre_rw()
{
TS_SKIP("");
auto path = path_helper::get_data_directory("10_default-libre-office.xlsx");
TS_ASSERT(round_trip_matches_rw(path));
}
void test_round_trip_empty_numbers_rw()
{
TS_SKIP("");
auto path = path_helper::get_data_directory("10_default-numbers.xlsx");
TS_ASSERT(round_trip_matches_rw(path));
}
void test_round_trip_all_styles_rw()
{
auto path = path_helper::get_data_directory("13_all_styles.xlsx");
@ -109,6 +114,6 @@ public:
std::vector<std::uint8_t> buffer;
original_workbook.save(buffer);
//TS_ASSERT(round_trip_matches_rw(path));
TS_ASSERT(round_trip_matches_rw(path));
}
};

View File

@ -483,15 +483,16 @@ void workbook::register_comments_in_manifest(worksheet ws)
{
std::size_t file_number = 1;
path filename("vmlDrawing1.vml");
bool filename_exists = true;
while (true)
while (filename_exists)
{
bool filename_exists = false;
filename_exists = false;
for (auto current_ws_rel : get_manifest().get_relationships(wb_rel.get_target().get_path(), xlnt::relationship_type::worksheet))
{
path current_ws_path(current_ws_rel.get_source().get_path().parent().append(current_ws_rel.get_target().get_path()));
if (!get_manifest().has_relationship(current_ws_path, xlnt::relationship_type::vml_drawing)) break;
if (!get_manifest().has_relationship(current_ws_path, xlnt::relationship_type::vml_drawing)) continue;
for (auto current_ws_child_rel : get_manifest().get_relationships(current_ws_path, xlnt::relationship_type::vml_drawing))
{
@ -501,17 +502,13 @@ void workbook::register_comments_in_manifest(worksheet ws)
break;
}
}
}
if (filename_exists)
{
break;
}
}
if (!filename_exists) break;
file_number++;
filename = path("vmlDrawing" + std::to_string(file_number) + ".vml");
}
}
get_manifest().register_default_type("vml",

View File

@ -199,7 +199,8 @@ public:
auto is_xml = (content_type.substr(0, 12) == "application/"
&& content_type.substr(content_type.size() - 4) == "+xml")
|| content_type == "application/xml"
|| content_type == "[Content_Types].xml";
|| content_type == "[Content_Types].xml"
|| content_type == "application/vnd.openxmlformats-officedocument.vmlDrawing";
if (is_xml)
{

2
third-party/botan vendored

@ -1 +1 @@
Subproject commit 523b2a4ca48fa5cf04ea371aabe7167ce2e5cd13
Subproject commit 923a95d546df5b6d31f39b0af900d0361fb2e6a6