summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/reference_tree.ml28
-rw-r--r--test/data/interface_definition_sample.xml17
-rw-r--r--test/reference_tree_test.ml10
3 files changed, 47 insertions, 8 deletions
diff --git a/src/reference_tree.ml b/src/reference_tree.ml
index 5243e82..61e1efa 100644
--- a/src/reference_tree.ml
+++ b/src/reference_tree.ml
@@ -127,7 +127,18 @@ let load_from_xml reftree file =
(* Validation function *)
-(* A path can be created in the config tree unless:
+let has_illegal_characters name =
+ (** Checks if string name has illegal characters in it.
+ All whitespace, curly braces, square brackets, and quotes
+ are disallowed due to their special significance to the curly config
+ format parser *)
+ try Some (Pcre.get_substring (Pcre.exec ~pat:"[\\s\\{\\}\\[\\]\"\'#]" name) 0)
+ with Not_found -> None
+
+(** Takes a list of string that represents a configuration path that may have
+ node value at the end, validates it, and splits it into path and value parts.
+
+ A list of strings is a valid path that can be created in the config tree unless:
1. It's a tag node without a child
2. It's a non-valueless leaf node without a value
3. It's a valueless node with a value
@@ -156,12 +167,15 @@ let rec validate_path validators_dir node path =
| Tag ->
(match path with
| p :: p' :: ps ->
- if (Value_checker.validate_any validators_dir data.constraints p) then
- let child = Vytree.find node p' in
- (match child with
- | Some c -> aux c ps (p' :: p :: acc)
- | None -> raise (Validation_error (Printf.sprintf "Node %s has no child %s" (show_path acc) p')))
- else raise (Validation_error (Printf.sprintf "%s is not a valid child name for node %s" p (show_path acc)))
+ (match (has_illegal_characters p) with
+ | Some c -> raise (Validation_error (Printf.sprintf "Illegal character \"%s\" in node name \"%s\"" c p))
+ | None ->
+ if (Value_checker.validate_any validators_dir data.constraints p) then
+ let child = Vytree.find node p' in
+ (match child with
+ | Some c -> aux c ps (p' :: p :: acc)
+ | None -> raise (Validation_error (Printf.sprintf "Node %s has no child %s" (show_path acc) p')))
+ else raise (Validation_error (Printf.sprintf "%s is not a valid child name for node %s" p (show_path acc))))
| [p] -> if (Value_checker.validate_any validators_dir data.constraints p) then (List.rev acc, None)
else raise (Validation_error (Printf.sprintf "Node %s has no child %s" (show_path acc) p))
| _ -> raise (Validation_error (Printf.sprintf "Path %s is incomplete" (show_path acc))))
diff --git a/test/data/interface_definition_sample.xml b/test/data/interface_definition_sample.xml
index c6185c0..292231e 100644
--- a/test/data/interface_definition_sample.xml
+++ b/test/data/interface_definition_sample.xml
@@ -60,4 +60,21 @@
</node>
</children>
</node>
+ <node name="interfaces">
+ <children>
+ <tagNode name="ethernet">
+ <properties>
+ <!-- no constraint, for testing if tag nodes with invalid characters in names
+ are detected -->
+ </properties>
+ <children>
+ <leafNode name="disable">
+ <properties>
+ <valueless/>
+ </properties>
+ </leafNode>
+ </children>
+ </tagNode>
+ </children>
+ </node>
</interfaceDefinition>
diff --git a/test/reference_tree_test.ml b/test/reference_tree_test.ml
index 6dfac5a..8002bdf 100644
--- a/test/reference_tree_test.ml
+++ b/test/reference_tree_test.ml
@@ -10,7 +10,8 @@ let raises_validation_error f =
let test_load_valid_definition test_ctxt =
let r = Vytree.make default_data "root" in
let r = load_from_xml r (in_testdata_dir test_ctxt ["interface_definition_sample.xml"]) in
- assert_equal (Vytree.list_children r) ["system"]
+ assert_equal (Vylist.in_list (Vytree.list_children r) "system") true;
+ assert_equal (Vylist.in_list (Vytree.list_children r) "interfaces") true
(* Path validation tests *)
let test_validate_path_leaf_valid test_ctxt =
@@ -34,6 +35,12 @@ let test_validate_path_tag_node_complete_valid test_ctxt =
assert_equal (validate_path (get_dir test_ctxt) r ["system"; "login"; "user"; "test"; "full-name"; "test user"])
(["system"; "login"; "user"; "test"; "full-name";], Some "test user")
+let test_validate_path_tag_node_illegal_characters test_ctxt =
+ let r = Vytree.make default_data "root" in
+ let r = load_from_xml r (in_testdata_dir test_ctxt ["interface_definition_sample.xml"]) in
+ (* the space in "eth 0" is on purpose *)
+ assert_equal (raises_validation_error (fun () -> ignore @@ validate_path (get_dir test_ctxt) r ["interfaces"; "ethernet"; "eth 0"; "disable"])) true
+
let test_validate_path_tag_node_invalid_name test_ctxt =
let r = Vytree.make default_data "root" in
let r = load_from_xml r (in_testdata_dir test_ctxt ["interface_definition_sample.xml"]) in
@@ -157,6 +164,7 @@ let suite =
"test_validate_path_leaf_valid" >:: test_validate_path_leaf_valid;
"test_validate_path_leaf_invalid" >:: test_validate_path_leaf_invalid;
"test_validate_path_leaf_incomplete" >:: test_validate_path_leaf_incomplete;
+ "test_validate_path_tag_node_illegal_characters" >:: test_validate_path_tag_node_illegal_characters;
"test_validate_path_tag_node_complete_valid" >:: test_validate_path_tag_node_complete_valid;
"test_validate_path_tag_node_invalid_name" >:: test_validate_path_tag_node_invalid_name;
"test_validate_path_tag_node_incomplete" >:: test_validate_path_tag_node_incomplete;