From b74e99b10bd12fcfab34fa9d60dce42be1194ffa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Thu, 30 Sep 2021 08:59:03 +0200 Subject: [PATCH] monitor-config-store: Make parsing a bit more forgiving Allow unknown XML elements inside . This makes extending in the future easier. Part-of: --- src/backends/meta-monitor-config-store.c | 54 +++++++++++++++--- .../monitor-configs/unknown-elements.xml | 31 ++++++++++ src/tests/monitor-store-unit-tests.c | 56 +++++++++++++++++++ 3 files changed, 133 insertions(+), 8 deletions(-) create mode 100644 src/tests/monitor-configs/unknown-elements.xml diff --git a/src/backends/meta-monitor-config-store.c b/src/backends/meta-monitor-config-store.c index 4dd357a15..3c69157ea 100644 --- a/src/backends/meta-monitor-config-store.c +++ b/src/backends/meta-monitor-config-store.c @@ -136,6 +136,7 @@ G_DEFINE_QUARK (meta-monitor-config-store-error-quark, typedef enum { STATE_INITIAL, + STATE_UNKNOWN, STATE_MONITORS, STATE_CONFIGURATION, STATE_MIGRATED, @@ -180,12 +181,28 @@ typedef struct MetaLogicalMonitorConfig *current_logical_monitor_config; GList *current_disabled_monitor_specs; + ParserState unknown_state_root; + int unknown_level; + MetaMonitorsConfigFlag extra_config_flags; } ConfigParser; G_DEFINE_TYPE (MetaMonitorConfigStore, meta_monitor_config_store, G_TYPE_OBJECT) +static void +enter_unknown_element (ConfigParser *parser, + const char *element_name, + const char *root_element_name, + ParserState root_state) +{ + parser->state = STATE_UNKNOWN; + parser->unknown_level = 1; + parser->unknown_state_root = root_state; + g_warning ("Unknown element <%s> under <%s>, ignoring", + element_name, root_element_name); +} + static void handle_start_element (GMarkupParseContext *context, const char *element_name, @@ -242,8 +259,8 @@ handle_start_element (GMarkupParseContext *context, { if (!g_str_equal (element_name, "configuration")) { - g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, - "Invalid toplevel element '%s'", element_name); + enter_unknown_element (parser, element_name, + "monitors", STATE_MONITORS); return; } @@ -253,6 +270,13 @@ handle_start_element (GMarkupParseContext *context, return; } + case STATE_UNKNOWN: + { + parser->unknown_level++; + + return; + } + case STATE_CONFIGURATION: { if (g_str_equal (element_name, "logicalmonitor")) @@ -274,9 +298,8 @@ handle_start_element (GMarkupParseContext *context, } else { - g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, - "Invalid configuration element '%s'", element_name); - return; + enter_unknown_element (parser, element_name, + "configuration", STATE_CONFIGURATION); } return; @@ -323,9 +346,8 @@ handle_start_element (GMarkupParseContext *context, } else { - g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, - "Invalid monitor logicalmonitor element '%s'", element_name); - return; + enter_unknown_element (parser, element_name, + "logicalmonitor", STATE_LOGICAL_MONITOR); } return; @@ -793,6 +815,18 @@ handle_end_element (GMarkupParseContext *context, return; } + case STATE_UNKNOWN: + { + parser->unknown_level--; + if (parser->unknown_level == 0) + { + g_assert (parser->unknown_state_root >= 0); + parser->state = parser->unknown_state_root; + parser->unknown_state_root = -1; + } + return; + } + case STATE_MONITORS: { g_assert (g_str_equal (element_name, "monitors")); @@ -912,6 +946,9 @@ handle_text (GMarkupParseContext *context, switch (parser->state) { + case STATE_UNKNOWN: + return; + case STATE_INITIAL: case STATE_MONITORS: case STATE_CONFIGURATION: @@ -1099,6 +1136,7 @@ read_config_file (MetaMonitorConfigStore *config_store, .state = STATE_INITIAL, .config_store = config_store, .extra_config_flags = extra_config_flags, + .unknown_state_root = -1, }; parse_context = g_markup_parse_context_new (&config_parser, diff --git a/src/tests/monitor-configs/unknown-elements.xml b/src/tests/monitor-configs/unknown-elements.xml new file mode 100644 index 000000000..f81be95dd --- /dev/null +++ b/src/tests/monitor-configs/unknown-elements.xml @@ -0,0 +1,31 @@ + + + text + + + + text + + + + text + + 0 + 0 + yes + + + DP-1 + MetaProduct's Inc. + MetaMonitor + 0x123456 + + + 1920 + 1080 + 60.000495910644531 + + + + + diff --git a/src/tests/monitor-store-unit-tests.c b/src/tests/monitor-store-unit-tests.c index b9d5622b7..64618174f 100644 --- a/src/tests/monitor-store-unit-tests.c +++ b/src/tests/monitor-store-unit-tests.c @@ -836,6 +836,60 @@ meta_test_monitor_store_interlaced (void) check_monitor_store_configurations (&expect); } +static void +meta_test_monitor_store_unknown_elements (void) +{ + MonitorStoreTestExpect expect = { + .configurations = { + { + .logical_monitors = { + { + .layout = { + .x = 0, + .y = 0, + .width = 1920, + .height = 1080 + }, + .scale = 1, + .is_primary = TRUE, + .is_presentation = FALSE, + .monitors = { + { + .connector = "DP-1", + .vendor = "MetaProduct's Inc.", + .product = "MetaMonitor", + .serial = "0x123456", + .mode = { + .width = 1920, + .height = 1080, + .refresh_rate = 60.000495910644531 + } + } + }, + .n_monitors = 1, + } + }, + .n_logical_monitors = 1 + } + }, + .n_configurations = 1 + }; + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, + "Unknown element " + "under , ignoring"); + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, + "Unknown element " + "under , ignoring"); + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, + "Unknown element " + "under , ignoring"); + set_custom_monitor_config ("unknown-elements.xml"); + g_test_assert_expected_messages (); + + check_monitor_store_configurations (&expect); +} + void init_monitor_store_tests (void) { @@ -861,4 +915,6 @@ init_monitor_store_tests (void) meta_test_monitor_store_second_rotated); g_test_add_func ("/backends/monitor-store/interlaced", meta_test_monitor_store_interlaced); + g_test_add_func ("/backends/monitor-store/unknown-elements", + meta_test_monitor_store_unknown_elements); }