[OpenWrt-Devel] [PATCH 0/4] Add multi-line option value support to UCI config file parser.

Yousong Zhou yszhou4tech at gmail.com
Thu Nov 6 15:21:44 EST 2014

I am not quite familiar with the early history of how UCI file was parsed, but
thought that UCI config files were parsed in a quite clever way all by shell
scripts which made it possible to have multi-line value for options.  AFAIK, at
least package openvpn [1] depends on this feature.

This series tries to fix an issue with current C implementation of parser for
UCI config file.  The current code uses pointers into line buffer
`ctx->pctx->buf` which may need to grow in size when a backslash was found at
the end of line.  The grow is implemented by function uci_realloc() which may
return an address different from the original.  Then the parser will be in a
state where ctx->pctx->buf changed, but various char **str and char **target
are not updated along.

The realloc() can be triggered by something like below (in function

	config sockd 'instance0'
	    option internal_network 'vpn'
	    option external_network 'wan'
	    option extra_config "a \
		 bbbbbbbbbbbbb \
		 ccccccccccccc \

A few test cases, including importing/exporting config, getting/setting option
values were also included trying to verify the patch.

I do not expect this to be accepted in the neare future because at later stage
of preparing this series I saw that LF and NL characters are explicitly deemed
illegal for option value in uci_validate_text().  But if you are interested in
this feature, you can give it a try.

I found multi-line option value useful in cases where I want parts of the
program's configuration values to be connected with OpenWrt system state, e.g.
stop/start services when the status of the dependent network go down/up, while
still keep the related bits all in one place, not just many remedy scripts
scattered here and there.

[1] see `append_params()` in package/network/services/openvpn/files/openvpn.init

Yousong Zhou (4):
  Drop test cases for deprecated ucimap-example.
  Sync ref test result with current implementation.
  Use offset into parser buffer to avoid potential heap overflow.
  Add test coverage for multi-line option value.

 delta.c                                            |   15 +-
 file.c                                             |  216 +++++++++++---------
 test/references/add_section.result                 |    2 +-
 test/references/export.data                        |    7 +-
 test/references/export.result                      |   15 +-
 test/references/get_multiline.data                 |    5 +
 test/references/import.data                        |    7 +-
 test/references/import.result                      |   13 +-
 test/references/set_existing_option.result         |    2 +-
 .../set_existing_option_multiline.result           |    2 +
 test/references/set_named_section.result           |    2 +-
 test/references/set_nonexisting_option.result      |    2 +-
 .../set_nonexisting_option_multiline.result        |    2 +
 test/references/set_parsing_multiline.data         |    2 +
 test/tests.d/020_get                               |    9 +
 test/tests.d/030_set                               |   16 ++
 test/tests.d/060-ucimap_example                    |    9 -
 uci_internal.h                                     |    8 +-
 util.c                                             |   11 +-
 19 files changed, 218 insertions(+), 127 deletions(-)
 create mode 100644 test/references/get_multiline.data
 create mode 100644 test/references/set_existing_option_multiline.result
 create mode 100644 test/references/set_nonexisting_option_multiline.result
 create mode 100644 test/references/set_parsing_multiline.data
 delete mode 100644 test/tests.d/060-ucimap_example

openwrt-devel mailing list
openwrt-devel at lists.openwrt.org

More information about the openwrt-devel mailing list