If none of the markers bears type information we can't just prepend a new one. Otherwise two subsequent markers will begin at offset 0, blowing up the chunk_len calculation a few lines after. A particular case where this causes havoc is a string property in a tree generated from "fs" input. A string property ends up with a TYPE_NULL marker. Upon output, in write_propval(), we correctly guess it looks like a TYPE_STRING. With the dummy marker prepended, We'd and up with two markers: { type = TYPE_STRING, offset = 0 } { type = TYPE_NONE, offset = 0 } The chunk_len for the fist marker will end up being calculated as 0. This blows up later on because a zero-length string should never happen because it lacks the terminating \0 (valgrind catches this). I'm also adding an assertion to write_propval_string() so that such cases won't go unnoticed in future and a test case. Signed-off-by: Lubomir Rintel <lkundrak@xxxxx> --- tests/run_tests.sh | 14 ++++++++++++++ treesource.c | 3 ++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/tests/run_tests.sh b/tests/run_tests.sh index 0e9f345..f8cc481 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -137,6 +137,19 @@ check_align () { ) } +# $1: first file +# $2: second file +files_equal () { + shorten_echo "files_equal $@: " + ( + if diff -q $1 $2; then + PASS + else + FAIL "File $1 differs from $2" + fi + ) +} + run_dtc_test () { printf "dtc $*: " base_run_test wrap_test $VALGRIND $DTC "$@" @@ -460,6 +473,7 @@ libfdt_tests () { run_dtc_test -I fs -O dts -o fs.test_tree1.test.dts $FSBASE/test_tree1 run_dtc_test -I fs -O dtb -o fs.test_tree1.test.dtb $FSBASE/test_tree1 run_test dtbs_equal_unordered -m fs.test_tree1.test.dtb test_tree1.dtb + base_run_test files_equal fs_tree1.dts fs.test_tree1.test.dts # check full tests for good in test_tree1.dtb; do diff --git a/treesource.c b/treesource.c index c1fdb86..eabb929 100644 --- a/treesource.c +++ b/treesource.c @@ -64,6 +64,7 @@ static bool isstring(char c) static void write_propval_string(FILE *f, const char *s, size_t len) { const char *end = s + len - 1; + assert(len > 0); assert(*end == '\0'); fprintf(f, "\""); @@ -221,7 +222,7 @@ static void write_propval(FILE *f, struct property *prop) if (!next_type_marker(m)) { /* data type information missing, need to guess */ dummy_marker.type = guess_value_type(prop); - dummy_marker.next = prop->val.markers; + dummy_marker.next = NULL; dummy_marker.offset = 0; dummy_marker.ref = NULL; m = &dummy_marker; -- 2.19.0