diff --git a/repos/base/include/util/xml_generator.h b/repos/base/include/util/xml_generator.h index 7939943302..615e3118bc 100644 --- a/repos/base/include/util/xml_generator.h +++ b/repos/base/include/util/xml_generator.h @@ -252,10 +252,17 @@ class Genode::Xml_generator xml._curr_node = this; xml._curr_indent++; - /* - * Process attributes and sub nodes - */ - func(); + try { + /* + * Process attributes and sub nodes + */ + func(); + } catch (...) { + /* reset and drop changes by not committing it */ + xml._curr_node = _parent_node; + xml._curr_indent--; + throw; + } xml._curr_node = _parent_node; xml._curr_indent--; diff --git a/repos/os/run/xml_generator.run b/repos/os/run/xml_generator.run index 67f1fff21a..076d60b0f7 100644 --- a/repos/os/run/xml_generator.run +++ b/repos/os/run/xml_generator.run @@ -48,5 +48,31 @@ compare_output_to { [init -> test-xml_generator] [init -> test-xml_generator] used 307 bytes [init -> test-xml_generator] buffer exceeded (expected error) + [init -> test-xml_generator] + [init -> test-xml_generator] exception on level3 (expected exception value=10) + [init -> test-xml_generator] exception on level3 (expected exception value=11) + [init -> test-xml_generator] exception on level3 (expected exception value=12) + [init -> test-xml_generator] + [init -> test-xml_generator] used 183 bytes, result: + [init -> test-xml_generator] + [init -> test-xml_generator] <config> + [init -> test-xml_generator] <level1> + [init -> test-xml_generator] <level2> + [init -> test-xml_generator] + [init -> test-xml_generator] <level3> + [init -> test-xml_generator] <level4/> + [init -> test-xml_generator] </level3> + [init -> test-xml_generator] + [init -> test-xml_generator] <level3> + [init -> test-xml_generator] <level4/> + [init -> test-xml_generator] </level3> + [init -> test-xml_generator] + [init -> test-xml_generator] <level3> + [init -> test-xml_generator] <level4/> + [init -> test-xml_generator] </level3> + [init -> test-xml_generator] </level2> + [init -> test-xml_generator] </level1> + [init -> test-xml_generator] </config> + [init -> test-xml_generator] [init -> test-xml_generator] --- XML generator test finished --- } diff --git a/repos/os/src/test/xml_generator/main.cc b/repos/os/src/test/xml_generator/main.cc index c013139d81..cb6b7448aa 100644 --- a/repos/os/src/test/xml_generator/main.cc +++ b/repos/os/src/test/xml_generator/main.cc @@ -63,6 +63,35 @@ static size_t fill_buffer_with_xml(char *dst, size_t dst_len) } +static size_t xml_with_exceptions(char *dst, size_t dst_len) +{ + Genode::Xml_generator xml(dst, dst_len, "config", [&] + { + xml.node("level1", [&] () + { + xml.node("level2", [&] () + { + for (unsigned i=0; i < 3; i++) { + try { + xml.node("level3_exception", [&] () + { + throw 10 + i; + }); + } catch (unsigned error) { + Genode::log("exception on level3 (expected exception value=", error, ")"); + } + xml.node("level3", [&] () + { + xml.node("level4", [&] () { }); + }); + } + }); + }); + }); + return xml.used(); +} + + void Component::construct(Genode::Env &env) { using namespace Genode; @@ -84,7 +113,14 @@ void Component::construct(Genode::Env &env) try { fill_buffer_with_xml(dst, 20); } catch (Genode::Xml_generator::Buffer_exceeded) { - log("buffer exceeded (expected error)"); } + log("buffer exceeded (expected error)\n"); } + + /* + * Test throwing non-XML related exceptions during xml generation + */ + memset(dst, 0, sizeof(dst)); + used = xml_with_exceptions(dst, sizeof(dst)); + log("\nused ", used, " bytes, result:\n\n", Cstring(dst)); /* * Test the sanitizing of XML node content