From 1c7cb28f68b66fe68dad6a90da9b542a3d662ac7 Mon Sep 17 00:00:00 2001 From: Vincent Riquer Date: Tue, 26 Mar 2013 01:33:55 +0100 Subject: [PATCH] handle command lines safely --- atom | 298 ++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 225 insertions(+), 73 deletions(-) diff --git a/atom b/atom index 2b008e1..868a925 100755 --- a/atom +++ b/atom @@ -959,35 +959,39 @@ checkCopy() { } decodeSox() { + commandline=(sox --single-threaded --temp "$tempdir") + soxoptions_in='' + soxoptions_out='' if (( ${destinationnormalize["$destination"]} )) then - soxoptions_in+=" --norm" + commandline+=(--norm) + soxoptions_in+=' --norm' + fi + if [ -n "$1" ] + then + commandline+=("$1") + else + commandline+=("$sourcepath/$filename") fi if [ -n "${destinationfrequency["$destination"]}" ] \ && (( ${rate:-0} != ${destinationfrequency["$destination"]} )) then + commandline+=(-r ${destinationfrequency["$destination"]}) soxoptions_out+=" -r ${destinationfrequency["$destination"]}" fi if [ -n "${destinationchannels["$destination"]}" ] \ && (( ${channels:-0} != ${destinationchannels["$destination"]} )) then + commandline+=(-c ${destinationchannels["$destination"]}) soxoptions_out+=" -c ${destinationchannels["$destination"]}" fi tmpfile="$fileid${soxoptions_in// /}${soxoptions_out// /}" - soxoptions_in+=' --single-threaded' - soxoptions_out+=" --temp \"$tempdir\"" - if [ -n "$1" ] - then - origin="$1" - else - origin="$sourcepath/$filename" - fi - commandline="sox $soxoptions_in \"$origin\" $soxoptions_out \"$tempdir/$tmpfile.wav\"" + commandline+=("$tempdir/$tmpfile.wav") } decodeMpcdec() { tmpfile="${fileid}mpcdec" - commandline="mpcdec \"$sourcepath/$filename\" \"$tempdir/$tmpfile.wav\"" + commandline=(mpcdec "$sourcepath/$filename" "$tempdir/$tmpfile.wav") } decodeFile() { @@ -999,7 +1003,12 @@ decodeFile() { Insert tasks <<-EOInsert key $tmpfile source_file $fileid - command_line $commandline + $( + for key in ${!commandline[@]} + do + echo "cmd_arg$key ${commandline[key]}" + done + ) status 0 EOInsert ) @@ -1017,7 +1026,12 @@ decodeFile() { Insert tasks <<-EOInsert key $tmpfile source_file $fileid - command_line $commandline + $( + for key in ${!commandline[@]} + do + echo "cmd_arg$key ${commandline[key]}" + done + ) requires $decodetaskid required $decodetaskid status 0 @@ -1030,27 +1044,31 @@ decodeFile() { } copyFile() { - tmpfile="${fileid}copy$destination" extension="${filename##*.}" - commandline="cp -al \"$sourcepath/$filename\" \"$destdir/$destfile.$extension\"" - commandline+=" 2>/dev/null" - commandline+=' AtOM:OR ' - commandline+="cp -a \"$sourcepath/$filename\" \"$destdir/$destfile\"" - copytaskid=$( - Insert tasks <<-EOInsert - key ${fileid}copy$destination - source_file $fileid - command_line $commandline - status 0 - EOInsert - ) - progressSpin + cp -al \ + "$sourcepath/$filename" \ + "$destdir/$destfile.$extension" \ + 2>/dev/null \ + || cp -a \ + "$sourcepath/$filename" \ + "$destdir/$destfile.$extension" + echo \ + "UPDATE destination_files" \ + "SET filename=\"${filename//\"/\"\"}\"," \ + " last_change=(" \ + " SELECT last_change" \ + " FROM source_files" \ + " WHERE id=$fileid" \ + " )" \ + "WHERE id=$destfileid;" \ + >&3 + (( ++copies )) } sanitizeFile() { string="$1" # Filenames can't contain / - string="${strings//\// }" + string="${string//\// }" if (( ${destinationfat32compat[$destination]} )) then # Filenames can't contain: @@ -1117,13 +1135,13 @@ getDestFile() { } encodeFile::mp3() { - lameopts="--quiet -v --abr ${destinationquality[$destination]}" - [ -n "$album" ] && lameopts+=" --tl \"$album\"" - [ -n "$artist" ] && lameopts+=" --ta \"$artist\"" - [ -n "$genre" ] && lameopts+=" --tg \"$genre\"" - [ -n "$title" ] && lameopts+=" --tt \"$title\"" - [ -n "$track" ] && lameopts+=" --tn \"$track\"" - [ -n "$year" ] && lameopts+=" --ty \"$year\"" + lameopts=(lame --quiet -v --abr ${destinationquality[$destination]}) + [ -n "$album" ] && lameopts+=(--tl "$album" ) + [ -n "$artist" ] && lameopts+=(--ta "$artist") + [ -n "$genre" ] && lameopts+=(--tg "$genre") + [ -n "$title" ] && lameopts+=(--tt "$title") + [ -n "$track" ] && lameopts+=(--tn "$track") + [ -n "$year" ] && lameopts+=(--ty "$year") if (( ${destinationnoresample[$destination]:-0} == 1 )) then # If 'rate' is not one of these value, it cannot be encoded to @@ -1132,30 +1150,31 @@ encodeFile::mp3() { if [ -n "${destinationfrequency["$destination"]}" ] then case ${destinationfrequency["$destination"]} in - 48000) lameopts+=" --resample 48" ;; - 44100) lameopts+=" --resample 44.1" ;; - 32000) lameopts+=" --resample 32" ;; - 24000) lameopts+=" --resample 24" ;; - 22050) lameopts+=" --resample 22.05" ;; - 16000) lameopts+=" --resample 16" ;; - 12000) lameopts+=" --resample 12" ;; - 11025) lameopts+=" --resample 11.025" ;; - 8000) lameopts+=" --resample 8" ;; + 48000) lameopts+=(--resample 48) ;; + 44100) lameopts+=(--resample 44.1) ;; + 32000) lameopts+=(--resample 32) ;; + 24000) lameopts+=(--resample 24) ;; + 22050) lameopts+=(--resample 22.05) ;; + 16000) lameopts+=(--resample 16) ;; + 12000) lameopts+=(--resample 12) ;; + 11025) lameopts+=(--resample 11.025) ;; + 8000) lameopts+=(--resample 8) ;; esac else case $rate in - 48000) lameopts+=" --resample 48" ;; - 44100) lameopts+=" --resample 44.1" ;; - 32000) lameopts+=" --resample 32" ;; - 24000) lameopts+=" --resample 24" ;; - 22050) lameopts+=" --resample 22.05" ;; - 16000) lameopts+=" --resample 16" ;; - 12000) lameopts+=" --resample 12" ;; - 11025) lameopts+=" --resample 11.025" ;; - 8000) lameopts+=" --resample 8" ;; + 48000) lameopts+=(--resample 48) ;; + 44100) lameopts+=(--resample 44.1) ;; + 32000) lameopts+=(--resample 32) ;; + 24000) lameopts+=(--resample 24) ;; + 22050) lameopts+=(--resample 22.05) ;; + 16000) lameopts+=(--resample 16) ;; + 12000) lameopts+=(--resample 12) ;; + 11025) lameopts+=(--resample 11.025) ;; + 8000) lameopts+=(--resample 8) ;; esac fi fi + lameopts+=("$tempdir/$tmpfile.wav" "$destdir/$destfile.mp3") encodetaskid=$( Insert tasks <<-EOInsert key ${fileid}lame$destination @@ -1163,8 +1182,13 @@ encodeFile::mp3() { required ${soxtaskid:-$decodetaskid} fileid $destfileid filename $destdir/$destfile.mp3 - command_line lame $lameopts "$tempdir/$tmpfile.wav" "$destdir/$destfile.mp3" - cleanup "$tempdir/$tmpfile.wav" + $( + for key in ${!lameopts[@]} + do + echo "cmd_arg$key ${lameopts[key]}" + done + ) + cleanup $tempdir/$tmpfile.wav source_file $fileid status 0 EOInsert @@ -1173,17 +1197,18 @@ encodeFile::mp3() { } encodeFile::vorbis() { - oggencopts="-Q -q ${destinationquality[$destination]}" - [ -n "$albumartist" ] && oggencopts+=" -c \"ALBUMARTIST=$albumartist\"" - [ -n "$album" ] && oggencopts+=" -l \"$album\"" - [ -n "$artist" ] && oggencopts+=" -a \"$artist\"" - [ -n "$composer" ] && oggencopts+=" -c \"COMPOSER=$composer\"" - [ -n "$disc" ] && oggencopts+=" -c \"DISCNUMBER=$disc\"" - [ -n "$genre" ] && oggencopts+=" -G \"$genre\"" - [ -n "$performer" ] && oggencopts+=" -c \"PERFORMER=$performer\"" - [ -n "$title" ] && oggencopts+=" -t \"$title\"" - [ -n "$track" ] && oggencopts+=" -N \"$track\"" - [ -n "$year" ] && oggencopts+=" -d \"$year\"" + oggencopts=(oggenc -Q -q ${destinationquality[$destination]}) + [ -n "$albumartist" ] && oggencopts+=(-c "ALBUMARTIST=$albumartist") + [ -n "$album" ] && oggencopts+=(-l "$album") + [ -n "$artist" ] && oggencopts+=(-a "$artist") + [ -n "$composer" ] && oggencopts+=(-c "COMPOSER=$composer") + [ -n "$disc" ] && oggencopts+=(-c "DISCNUMBER=$disc") + [ -n "$genre" ] && oggencopts+=(-G "$genre") + [ -n "$performer" ] && oggencopts+=(-c "PERFORMER=$performer") + [ -n "$title" ] && oggencopts+=(-t "$title") + [ -n "$track" ] && oggencopts+=(-N "$track") + [ -n "$year" ] && oggencopts+=(-d "$year") + oggencopts+=(-o "$destdir/$destfile.ogg" "$tempdir/$tmpfile.wav") encodetaskid=$( Insert tasks <<-EOInsert key ${fileid}oggenc$destination @@ -1191,8 +1216,13 @@ encodeFile::vorbis() { required ${soxtaskid:-$decodetaskid} fileid $destfileid filename $destdir/$destfile.ogg - command_line oggenc $oggencopts -o "$destdir/$destfile.ogg" "$tempdir/$tmpfile.wav" - cleanup "$tempdir/$tmpfile.wav" + $( + for key in ${!oggencopts[@]} + do + echo "cmd_arg$key ${oggencopts[key]}" + done + ) + cleanup $tempdir/$tmpfile.wav source_file $fileid status 0 EOInsert @@ -1254,7 +1284,65 @@ worker() { rest=${rest#*|} required=${rest%%|*} rest=${rest#*|} - commandline=${rest%%|*} + cmd_arg=("${rest%%|*}") + rest=${rest#*|} + cmd_arg+=("${rest%%|*}") + rest=${rest#*|} + cmd_arg+=("${rest%%|*}") + rest=${rest#*|} + cmd_arg+=("${rest%%|*}") + rest=${rest#*|} + cmd_arg+=("${rest%%|*}") + rest=${rest#*|} + cmd_arg+=("${rest%%|*}") + rest=${rest#*|} + cmd_arg+=("${rest%%|*}") + rest=${rest#*|} + cmd_arg+=("${rest%%|*}") + rest=${rest#*|} + cmd_arg+=("${rest%%|*}") + rest=${rest#*|} + cmd_arg+=("${rest%%|*}") + rest=${rest#*|} + cmd_arg+=("${rest%%|*}") + rest=${rest#*|} + cmd_arg+=("${rest%%|*}") + rest=${rest#*|} + cmd_arg+=("${rest%%|*}") + rest=${rest#*|} + cmd_arg+=("${rest%%|*}") + rest=${rest#*|} + cmd_arg+=("${rest%%|*}") + rest=${rest#*|} + cmd_arg+=("${rest%%|*}") + rest=${rest#*|} + cmd_arg+=("${rest%%|*}") + rest=${rest#*|} + cmd_arg+=("${rest%%|*}") + rest=${rest#*|} + cmd_arg+=("${rest%%|*}") + rest=${rest#*|} + cmd_arg+=("${rest%%|*}") + rest=${rest#*|} + cmd_arg+=("${rest%%|*}") + rest=${rest#*|} + cmd_arg+=("${rest%%|*}") + rest=${rest#*|} + cmd_arg+=("${rest%%|*}") + rest=${rest#*|} + cmd_arg+=("${rest%%|*}") + rest=${rest#*|} + cmd_arg+=("${rest%%|*}") + rest=${rest#*|} + cmd_arg+=("${rest%%|*}") + rest=${rest#*|} + cmd_arg+=("${rest%%|*}") + rest=${rest#*|} + cmd_arg+=("${rest%%|*}") + rest=${rest#*|} + cmd_arg+=("${rest%%|*}") + rest=${rest#*|} + cmd_arg+=("${rest%%|*}") rest=${rest#*|} cleanup=${rest%%|*} rest=${rest#*|} @@ -1262,7 +1350,12 @@ worker() { rest=${rest#*|} destfilename=${rest%%|*} rest=${rest#*|} - if eval ${commandline/AtOM:OR/||} >/dev/null 2>>"$tempdir/errors.log" + for key in ${!cmd_arg[@]} + do + [ -z "${cmd_arg[key]}" ] && unset cmd_arg[key] + done + (( debug >= 2 )) && echo "${cmd_arg[@]}" >>"$tempdir/errors.log" + if "${cmd_arg[@]}" >/dev/null 2>>"$tempdir/errors.log" then echo "finished $taskid|$sourcefileid|$destfileid|$destfilename" else @@ -1270,6 +1363,7 @@ worker() { [ -n "$filename" ] \ && eval rm -f $filename fi + unset cmd_arg if [ -n "$cleanup" -a -n "$required" ] then echo "cleanup $required" @@ -1320,7 +1414,36 @@ master() { id, source_file, required, - command_line, + cmd_arg0, + cmd_arg1, + cmd_arg2, + cmd_arg3, + cmd_arg4, + cmd_arg5, + cmd_arg6, + cmd_arg7, + cmd_arg8, + cmd_arg9, + cmd_arg10, + cmd_arg11, + cmd_arg12, + cmd_arg13, + cmd_arg14, + cmd_arg15, + cmd_arg16, + cmd_arg17, + cmd_arg18, + cmd_arg19, + cmd_arg20, + cmd_arg21, + cmd_arg22, + cmd_arg23, + cmd_arg24, + cmd_arg25, + cmd_arg26, + cmd_arg27, + cmd_arg28, + cmd_arg29, cleanup, fileid, filename @@ -1597,7 +1720,36 @@ echo ' source_file INTEGER, fileid INTEGER, filename TEXT, - command_line TEXT, + cmd_arg0 TEXT, + cmd_arg1 TEXT, + cmd_arg2 TEXT, + cmd_arg3 TEXT, + cmd_arg4 TEXT, + cmd_arg5 TEXT, + cmd_arg6 TEXT, + cmd_arg7 TEXT, + cmd_arg8 TEXT, + cmd_arg9 TEXT, + cmd_arg10 TEXT, + cmd_arg11 TEXT, + cmd_arg12 TEXT, + cmd_arg13 TEXT, + cmd_arg14 TEXT, + cmd_arg15 TEXT, + cmd_arg16 TEXT, + cmd_arg17 TEXT, + cmd_arg18 TEXT, + cmd_arg19 TEXT, + cmd_arg20 TEXT, + cmd_arg21 TEXT, + cmd_arg22 TEXT, + cmd_arg23 TEXT, + cmd_arg24 TEXT, + cmd_arg25 TEXT, + cmd_arg26 TEXT, + cmd_arg27 TEXT, + cmd_arg28 TEXT, + cmd_arg29 TEXT, requires INTEGER, required INTEGER, status INTEGER NOT NULL, @@ -1795,7 +1947,7 @@ do tmpfile done echo 'COMMIT;' >&3 -echo -e "\rCreated ${count:-0} tasks for $filecount files" +echo -e "\rCreated ${count:-0} tasks for $filecount files (${copies:-0} immediate copies)" rm -f "$tempdir"/worker* concurrency=$(( maxload / 2 ))