[arch-projects] [mkinitcpio] [RFC] Rewrite parse_cmdline (again)
Dave Reisner
d at falconindy.com
Thu Apr 14 17:09:28 EDT 2011
On Thu, Apr 14, 2011 at 10:43:31PM +0200, Thomas Bächler wrote:
> This should properly handle all ugly characters in values,
> omit settings any forbidden variable names and take care
> of double-quoted values with spaces in them.
>
> This should finally fix FS#23467, FS#22080 and FS#13900.
> ---
>
> I screwed up the last fix for FS#23467 when trying to fix
> the other two. This should now handle all cases just fine,
> although it duplicates some of the work the kernel
> already does.
>
> I tested it better than 0.6.10 and it seems okay. Can
> someone please proof-read this and tell me if it is
> good?
Sandbox testing says this doesn't work. I feed in a file containing:
root=/dev/sda video="din:10 foo bar baz" quiet ro
and after parsing, i echo "root=$root" and "video=$video". i get...
video="din:10 foo bar baz
root=/dev/sda
I posted what I thought was a valid solution on FS#23467 from stack
overflow that seems to be a lot more sane and _much_ more maintainable.
For those who weren't following the report, I suggested that we use the
same fallback as /etc/fstab, which says to encode spaces with octal
sequences. These can then be decoded using printf's %b flag. It requires
only a simple change to the current parse_cmdline function.
I also never got a response as to where you're seeing pollution from
using export over eval. Sorry, but eval sucks hard and I've put a lot of
effort into _removing_ it from wherever I can in Arch code. It's
_rarely_ used properly. On top of it all, I've never seen any variables
declared on the command line populated into userspace.
Am I insane here?
d
>
> init_functions | 58 +++++++++++++++++++++++++++++++++++--------------------
> 1 files changed, 37 insertions(+), 21 deletions(-)
>
> diff --git a/init_functions b/init_functions
> index fd5bbb6..e29d696 100644
> --- a/init_functions
> +++ b/init_functions
> @@ -31,27 +31,43 @@ launch_interactive_shell() {
> }
>
> parse_cmdline() {
> - eval set -- $(cat /proc/cmdline)
> - for cmd in "$@"; do
> - case "${cmd}" in
> - \#*) break ;; # ignore everything after a # in the commandline
> - # The kernel passes those to the kernel on its own
> - [0123456Ss]) ;;
> - [0-9]*) ;;
> - single) ;;
> - rw) readwrite="yes" ;;
> - ro) readwrite="no" ;;
> - # only export stuff that does work with ash :)
> - *=*) rhs="$(echo "${cmd}" | cut -d= -f2-)"
> - cmd="$(echo "${cmd}" | cut -d= -f1 | sed 's|\.|_|g')"
> - cmd="$(echo "${cmd}" | sed 's|-|_|g')=\"${rhs}\""
> - (echo "${cmd}" | grep -qe '^[0-9]') || eval "${cmd}"
> - ;;
> - *) cmd="$(echo "${cmd}" | sed 's|\.|_|g')"
> - cmd="$(echo "${cmd}" | sed 's|-|_|g')"
> - (echo "${cmd}" | grep -qe '^[0-9]') || eval "${cmd}=y"
> - ;;
> - esac
> + local w in_quotes lhs rhs
> + in_quotes=0
> + for w in $(cat /proc/cmdline); do
> + if [ ${in_quotes} -eq 0 ]; then
> + case "${w}" in
> + \#*) break ;; # ignore everything after a # in the commandline
> + # The kernel passes those to init on its own
> + [0123456Ss]) ;;
> + single) ;;
> + rw) readwrite="yes" ;;
> + ro) readwrite="no" ;;
> + # only export stuff that does work with ash :)
> + *=*) rhs="$(echo "${w}" | cut -d= -f2-)"
> + lhs="$(echo "${w}" | cut -d= -f1 | sed 's|\.|_|g;s|-|_|g;')"
> + if [ "${rhs:0:1}" = "\"" ]; then
> + if [ "${rhs:$((${#rhs}-1))}" = "\"" ]; then
> + rhs="${rhs:1:$((${#rhs}-2))}"
> + else
> + in_quotes=1
> + continue
> + fi
> + fi
> + (echo "${lhs}" | grep -qe '^[0-9]' -e '[^a-zA-Z0-9_]') || eval ${lhs}=\${rhs}
> + ;;
> + *) lhs="$(echo "${w}" | sed 's|\.|_|g;s|-|_|g;')"
> + (echo "${lhs}" | grep -qe '^[0-9]' -e '[^a-zA-Z0-9_]') || eval ${lhs}=y
> + ;;
> + esac
> + else
> + if [ "${w:$((${#w}-1))}" = "\"" ]; then
> + rhs="${rhs} ${w:0:$((${#w}-1))}"
> + in_quotes=0
> + (echo "${lhs}" | grep -qe '^[0-9]' -e '[^a-zA-Z0-9_]') || eval ${lhs}=\${rhs}
> + else
> + rhs="${rhs} ${w}"
> + fi
> + fi
> done
> }
>
> --
> 1.7.4.4
>
More information about the arch-projects
mailing list