mirror of
https://github.com/tfussell/xlnt.git
synced 2024-03-22 13:11:17 +08:00
clean up xml parsing, fix numbers xlsx decryption, unskip some tests
This commit is contained in:
parent
6653568a1c
commit
2cc3f7947a
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#include <detail/constants.hpp>
|
#include <detail/constants.hpp>
|
||||||
#include <xlnt/xlnt_config.hpp>
|
#include <xlnt/xlnt_config.hpp>
|
||||||
|
#include <xlnt/utils/exceptions.hpp>
|
||||||
|
|
||||||
namespace xlnt {
|
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 =
|
static const std::unordered_map<std::string, std::string> *namespaces =
|
||||||
new std::unordered_map<std::string, std::string>
|
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" },
|
{ "content-types", "http://schemas.openxmlformats.org/package/2006/content-types" },
|
||||||
{ "relationships", "http://schemas.openxmlformats.org/package/2006/relationships" },
|
{ "relationships", "http://schemas.openxmlformats.org/package/2006/relationships" },
|
||||||
{ "drawingml", "http://schemas.openxmlformats.org/drawingml/2006/main" },
|
{ "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)
|
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
|
@ -35,6 +35,7 @@
|
||||||
|
|
||||||
namespace xlnt {
|
namespace xlnt {
|
||||||
|
|
||||||
|
class formatted_text;
|
||||||
class path;
|
class path;
|
||||||
class relationship;
|
class relationship;
|
||||||
class workbook;
|
class workbook;
|
||||||
|
@ -220,13 +221,31 @@ private:
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void read_unknown_relationships();
|
void read_unknown_relationships();
|
||||||
|
|
||||||
|
std::vector<relationship> read_relationships(const path &part);
|
||||||
|
|
||||||
std::string read_text();
|
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 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>
|
/// <summary>
|
||||||
/// The ZIP file containing the files that make up the OOXML package.
|
/// The ZIP file containing the files that make up the OOXML package.
|
||||||
|
@ -255,6 +274,8 @@ private:
|
||||||
/// to access the object.
|
/// to access the object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
xml::parser *parser_;
|
xml::parser *parser_;
|
||||||
|
|
||||||
|
std::vector<xml::qname> stack_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
|
@ -586,6 +586,7 @@ struct crypto_helper
|
||||||
= { {0xd7, 0xaa, 0x0f, 0x6d, 0x30, 0x61, 0x34, 0x4e} };
|
= { {0xd7, 0xaa, 0x0f, 0x6d, 0x30, 0x61, 0x34, 0x4e} };
|
||||||
auto expected_verifier = calculate_block(h_n, verifier_block_key,
|
auto expected_verifier = calculate_block(h_n, verifier_block_key,
|
||||||
result.key_encryptor.verifier_hash_value);
|
result.key_encryptor.verifier_hash_value);
|
||||||
|
expected_verifier.resize(calculated_verifier.size());
|
||||||
|
|
||||||
if (calculated_verifier.size() != expected_verifier.size()
|
if (calculated_verifier.size() != expected_verifier.size()
|
||||||
|| std::mismatch(calculated_verifier.begin(), calculated_verifier.end(),
|
|| std::mismatch(calculated_verifier.begin(), calculated_verifier.end(),
|
||||||
|
|
|
@ -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_mc = constants::get_namespace("mc");
|
||||||
static const auto &xmlns_mx = constants::get_namespace("mx");
|
static const auto &xmlns_mx = constants::get_namespace("mx");
|
||||||
static const auto &xmlns_r = constants::get_namespace("r");
|
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_x15 = constants::get_namespace("x15");
|
||||||
static const auto &xmlns_x15ac = constants::get_namespace("x15ac");
|
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*/)
|
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().start_element(xmlns, "sst");
|
||||||
serializer().namespace_decl(xmlns, "");
|
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*/)
|
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_mc = constants::get_namespace("mc");
|
||||||
static const auto &xmlns_x14 = constants::get_namespace("x14");
|
static const auto &xmlns_x14 = constants::get_namespace("x14");
|
||||||
static const auto &xmlns_x14ac = constants::get_namespace("x14ac");
|
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)
|
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_r = constants::get_namespace("r");
|
||||||
static const auto &xmlns_mc = constants::get_namespace("mc");
|
static const auto &xmlns_mc = constants::get_namespace("mc");
|
||||||
static const auto &xmlns_x14ac = constants::get_namespace("x14ac");
|
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,
|
void xlsx_producer::write_comments(const relationship &/*rel*/, worksheet ws,
|
||||||
const std::vector<cell_reference> &cells)
|
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().start_element(xmlns, "comments");
|
||||||
serializer().namespace_decl(xmlns, "");
|
serializer().namespace_decl(xmlns, "");
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
#include <helpers/path_helper.hpp>
|
#include <helpers/path_helper.hpp>
|
||||||
#include <xlnt/workbook/workbook.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
|
#define TEST_CRYPTO true
|
||||||
|
|
||||||
#ifndef TEST_CRYPTO
|
#ifndef TEST_CRYPTO
|
||||||
|
@ -42,7 +44,6 @@ public:
|
||||||
|
|
||||||
void test_decrypt_numbers()
|
void test_decrypt_numbers()
|
||||||
{
|
{
|
||||||
TS_SKIP("");
|
|
||||||
xlnt::workbook wb;
|
xlnt::workbook wb;
|
||||||
#if TEST_CRYPTO
|
#if TEST_CRYPTO
|
||||||
wb.load(path_helper::get_data_directory("17_encrypted_numbers.xlsx"), "secret");
|
wb.load(path_helper::get_data_directory("17_encrypted_numbers.xlsx"), "secret");
|
||||||
|
|
|
@ -43,7 +43,6 @@ public:
|
||||||
|
|
||||||
void test_produce_default_libre_office()
|
void test_produce_default_libre_office()
|
||||||
{
|
{
|
||||||
TS_SKIP("");
|
|
||||||
xlnt::workbook wb = xlnt::workbook::empty_libre_office();
|
xlnt::workbook wb = xlnt::workbook::empty_libre_office();
|
||||||
TS_ASSERT(workbook_matches_file(wb, path_helper::get_data_directory("10_default-libre-office.xlsx")));
|
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");
|
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")));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -70,14 +70,13 @@ public:
|
||||||
|
|
||||||
void test_round_trip_empty_libre_office_wrw()
|
void test_round_trip_empty_libre_office_wrw()
|
||||||
{
|
{
|
||||||
TS_SKIP("");
|
|
||||||
xlnt::workbook wb = xlnt::workbook::empty_libre_office();
|
xlnt::workbook wb = xlnt::workbook::empty_libre_office();
|
||||||
TS_ASSERT(round_trip_matches_wrw(wb));
|
TS_ASSERT(round_trip_matches_wrw(wb));
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_round_trip_empty_pages_wrw()
|
void test_round_trip_empty_numbers_wrw()
|
||||||
{
|
{
|
||||||
TS_SKIP("");
|
TS_SKIP("");
|
||||||
xlnt::workbook wb = xlnt::workbook::empty_numbers();
|
xlnt::workbook wb = xlnt::workbook::empty_numbers();
|
||||||
TS_ASSERT(round_trip_matches_wrw(wb));
|
TS_ASSERT(round_trip_matches_wrw(wb));
|
||||||
}
|
}
|
||||||
|
@ -96,11 +95,17 @@ public:
|
||||||
|
|
||||||
void test_round_trip_empty_libre_rw()
|
void test_round_trip_empty_libre_rw()
|
||||||
{
|
{
|
||||||
TS_SKIP("");
|
|
||||||
auto path = path_helper::get_data_directory("10_default-libre-office.xlsx");
|
auto path = path_helper::get_data_directory("10_default-libre-office.xlsx");
|
||||||
TS_ASSERT(round_trip_matches_rw(path));
|
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()
|
void test_round_trip_all_styles_rw()
|
||||||
{
|
{
|
||||||
auto path = path_helper::get_data_directory("13_all_styles.xlsx");
|
auto path = path_helper::get_data_directory("13_all_styles.xlsx");
|
||||||
|
@ -109,6 +114,6 @@ public:
|
||||||
|
|
||||||
std::vector<std::uint8_t> buffer;
|
std::vector<std::uint8_t> buffer;
|
||||||
original_workbook.save(buffer);
|
original_workbook.save(buffer);
|
||||||
//TS_ASSERT(round_trip_matches_rw(path));
|
TS_ASSERT(round_trip_matches_rw(path));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -483,15 +483,16 @@ void workbook::register_comments_in_manifest(worksheet ws)
|
||||||
{
|
{
|
||||||
std::size_t file_number = 1;
|
std::size_t file_number = 1;
|
||||||
path filename("vmlDrawing1.vml");
|
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))
|
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()));
|
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))
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filename_exists)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!filename_exists) break;
|
if (filename_exists)
|
||||||
|
{
|
||||||
file_number++;
|
file_number++;
|
||||||
filename = path("vmlDrawing" + std::to_string(file_number) + ".vml");
|
filename = path("vmlDrawing" + std::to_string(file_number) + ".vml");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get_manifest().register_default_type("vml",
|
get_manifest().register_default_type("vml",
|
||||||
|
|
|
@ -199,7 +199,8 @@ public:
|
||||||
auto is_xml = (content_type.substr(0, 12) == "application/"
|
auto is_xml = (content_type.substr(0, 12) == "application/"
|
||||||
&& content_type.substr(content_type.size() - 4) == "+xml")
|
&& content_type.substr(content_type.size() - 4) == "+xml")
|
||||||
|| content_type == "application/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)
|
if (is_xml)
|
||||||
{
|
{
|
||||||
|
|
2
third-party/botan
vendored
2
third-party/botan
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 523b2a4ca48fa5cf04ea371aabe7167ce2e5cd13
|
Subproject commit 923a95d546df5b6d31f39b0af900d0361fb2e6a6
|
Loading…
Reference in New Issue
Block a user