Modify

Opened 3 years ago

Last modified 3 years ago

#19539 new defect

uci / regression / lists contain wrong chars

Reported by: bittorf@… Owned by: developers
Priority: normal Milestone:
Component: packages Version: Trunk
Keywords: Cc: yszhou4tech@…

Description

with r45561 i can see on ar71xx:

root@box:~ uci show olsrd|grep interface=
olsrd.@Interface[0].interface='lan wan innercityVPN'
olsrd.@Interface[1].interface='wlanadhoc wlanadhocRADIO1 wlanadhocRADIO1'

root@box:~ uci get olsrd.@Interface[0].interface
'lan wan innercityVPN'

on e.g. r44942 this is not a problem (no leading/trailing "'"-chars

Attachments (0)

Change History (10)

comment:1 Changed 3 years ago by bittorf@…

please note, that this seems to happen only with lists:

root@box:~ uci show olsrd | grep arprefresh
olsrd.@LoadPlugin[0].library='olsrd_arprefresh.so.0.1'

root@box:~ uci get olsrd.@LoadPlugin[0].library
olsrd_arprefresh.so.0.1

this breaks some scripts here, because
list-elements are invalid/changed content.

comment:2 Changed 3 years ago by bittorf@…

so the minimal testcase is:

root@box:~ cat >>/etc/config/system <<EOF
config x
list y 'a b c'
EOF

root@box:~ uci get system.@x[0].y
'a b c'

in older versions of OpenWrt (e.g. r44945) it outputs (without quotes)
a b c

comment:3 follow-up: Changed 3 years ago by nbd

  • Cc yszhou4tech@… added

This seems to have been added intentionally, so that you can tell apart different list entries even if they contain whitespaces.
It would allow you to do something like this:

eval "set -- $(uci get network.@x[0].y)"; echo $1

It was added in uci commit ec302c635b27e212c2df5ce3378fd94edfbfd886.

I think it might make sense to rework this to only enable this new behavior through a command line flag.

comment:4 in reply to: ↑ 3 ; follow-up: Changed 3 years ago by bittorf@…

eval "set -- $(uci get network.@x[0].y)"; echo $1

the problem is, that you *dont know* if your "get" is
on a 'list' or or normal 'option'. it breaks especially:

VAR="$( uci get var )"

where you end up with changed content...

comment:5 in reply to: ↑ 4 Changed 3 years ago by yousong

Hi, bittorf and nbd,

Replying to bittorf@…:

so the minimal testcase is:

root@box:~ cat >>/etc/config/system <<EOF
config x
list y 'a b c'
EOF

root@box:~ uci get system.@x[0].y
'a b c'

in older versions of OpenWrt (e.g. r44945) it outputs (without quotes)
a b c

It is quoted because we really need a way to distinguish the single list value a b c from 3 list values a, b and c. Shell function config_list_foreach of /lib/functions.sh does this right and is used by at least package dnsmasq quite well.

IMHO, using list y 'a b c' to define a list type option consisting of 3 elements is kind of abusing the above ambiguity. It also will conflict with behaviours of config_list_foreach which is always there for quite a long time before the current change.

We can promote good practice with the current behaviour of uci command.

  • If 3 elements for a list option is intended, then three list y VAL is the right way to go.
  • If it is only a single value, then use option type.

Replying to bittorf@…:

eval "set -- $(uci get network.@x[0].y)"; echo $1

the problem is, that you *dont know* if your "get" is
on a 'list' or or normal 'option'. it breaks especially:

VAR="$( uci get var )"

where you end up with changed content...

Types of options in uci config files are expected to be well-defined, thus users are expected to know the type of option they are getting with uci get.

root@OpenWrt:~# cat /etc/config/p

config sec s
        list l '1 2'
        list l '3'
        option o '4 5 6'
root@OpenWrt:~# uci get p.s.l
'1 2' 3
root@OpenWrt:~# uci get p.s.o
4 5 6
root@OpenWrt:~# 

If var refers to a list type option, then VAR="$( uci get var )" is really a wrong way to fetching values of it.

comment:6 Changed 3 years ago by bittorf@…

i understand your detailed explanation, but i'am not happy with the changed behaviour:
e.g we have scripts like this:

LIST="$( uci get var )"
for OBJ in $LIST; do ... ; done

the list elements are now:
'a
b
c'

i'am also not happy with the idea of a commandline switch for explicitely enable this new feature, because it makes sense in the long run and is good. can we agree to only add single-quotes, when list elements have whitespaces in? so we are at least backward compatible...

comment:7 Changed 3 years ago by bittorf@…

ignore the last post, it's not correct...

comment:8 follow-up: Changed 3 years ago by bittorf@…

please close this ticket, i see no good way for fixing it - the new behaviour is correct - the old is just wrong and we have to change the way we interact with uci. my first idea was to output uci-vars with space like this:

root@box:~ for OBJ in a b1\ b2\ b3 c; do echo $OBJ; done
a
b1 b2 b3
c

but this has issues when uses in vars:

root@box:~ v1=a
root@box:~ v2=b1\ b2\ b3
root@box:~ v3=c
root@box:~ for OBJ in $v1 $v2 $v3; do echo $OBJ; done
a
b1
b2
b3
c

comment:9 in reply to: ↑ 8 Changed 3 years ago by ferry@…

Replying to bittorf@…:

please close this ticket, i see no good way for fixing it - the new behaviour is correct - the old is just wrong and we have to change the way we interact with uci. my first idea was to output uci-vars with space like this:

root@box:~ for OBJ in a b1\ b2\ b3 c; do echo $OBJ; done
a
b1 b2 b3
c

but this has issues when uses in vars:

root@box:~ v1=a
root@box:~ v2=b1\ b2\ b3
root@box:~ v3=c
root@box:~ for OBJ in $v1 $v2 $v3; do echo $OBJ; done

This should be

root@box:~ for OBJ in "$v1" "$v2" "$v3"; do echo "$OBJ"; done

Variables should always be quoted

a
b1
b2
b3
c
}}}

comment:10 Changed 3 years ago by ufo@…

please close ticket.. its a problem within luci-package "meshwizard"

dirty workaround, tested with openwrt cc-rc1 x86-64bit:

mkdir /tmp/etc
mkdir /tmp/etc/config
cd /etc/config
for i in `ls`; do cat $i  | sed s/\'\\\\\'\'//g   > /tmp/etc/config/$i; done
mv /tmp/etc/config/* .
reboot

Add Comment

Modify Ticket

Action
as new .
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.