handle command lines safely

This commit is contained in:
Vincent Riquer 2013-03-26 01:33:55 +01:00
parent 202a4fd6ca
commit 1c7cb28f68

298
atom
View File

@ -959,35 +959,39 @@ checkCopy() {
} }
decodeSox() { decodeSox() {
commandline=(sox --single-threaded --temp "$tempdir")
soxoptions_in=''
soxoptions_out=''
if (( ${destinationnormalize["$destination"]} )) if (( ${destinationnormalize["$destination"]} ))
then then
soxoptions_in+=" --norm" commandline+=(--norm)
soxoptions_in+=' --norm'
fi
if [ -n "$1" ]
then
commandline+=("$1")
else
commandline+=("$sourcepath/$filename")
fi fi
if [ -n "${destinationfrequency["$destination"]}" ] \ if [ -n "${destinationfrequency["$destination"]}" ] \
&& (( ${rate:-0} != ${destinationfrequency["$destination"]} )) && (( ${rate:-0} != ${destinationfrequency["$destination"]} ))
then then
commandline+=(-r ${destinationfrequency["$destination"]})
soxoptions_out+=" -r ${destinationfrequency["$destination"]}" soxoptions_out+=" -r ${destinationfrequency["$destination"]}"
fi fi
if [ -n "${destinationchannels["$destination"]}" ] \ if [ -n "${destinationchannels["$destination"]}" ] \
&& (( ${channels:-0} != ${destinationchannels["$destination"]} )) && (( ${channels:-0} != ${destinationchannels["$destination"]} ))
then then
commandline+=(-c ${destinationchannels["$destination"]})
soxoptions_out+=" -c ${destinationchannels["$destination"]}" soxoptions_out+=" -c ${destinationchannels["$destination"]}"
fi fi
tmpfile="$fileid${soxoptions_in// /}${soxoptions_out// /}" tmpfile="$fileid${soxoptions_in// /}${soxoptions_out// /}"
soxoptions_in+=' --single-threaded' commandline+=("$tempdir/$tmpfile.wav")
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\""
} }
decodeMpcdec() { decodeMpcdec() {
tmpfile="${fileid}mpcdec" tmpfile="${fileid}mpcdec"
commandline="mpcdec \"$sourcepath/$filename\" \"$tempdir/$tmpfile.wav\"" commandline=(mpcdec "$sourcepath/$filename" "$tempdir/$tmpfile.wav")
} }
decodeFile() { decodeFile() {
@ -999,7 +1003,12 @@ decodeFile() {
Insert tasks <<-EOInsert Insert tasks <<-EOInsert
key $tmpfile key $tmpfile
source_file $fileid source_file $fileid
command_line $commandline $(
for key in ${!commandline[@]}
do
echo "cmd_arg$key ${commandline[key]}"
done
)
status 0 status 0
EOInsert EOInsert
) )
@ -1017,7 +1026,12 @@ decodeFile() {
Insert tasks <<-EOInsert Insert tasks <<-EOInsert
key $tmpfile key $tmpfile
source_file $fileid source_file $fileid
command_line $commandline $(
for key in ${!commandline[@]}
do
echo "cmd_arg$key ${commandline[key]}"
done
)
requires $decodetaskid requires $decodetaskid
required $decodetaskid required $decodetaskid
status 0 status 0
@ -1030,27 +1044,31 @@ decodeFile() {
} }
copyFile() { copyFile() {
tmpfile="${fileid}copy$destination"
extension="${filename##*.}" extension="${filename##*.}"
commandline="cp -al \"$sourcepath/$filename\" \"$destdir/$destfile.$extension\"" cp -al \
commandline+=" 2>/dev/null" "$sourcepath/$filename" \
commandline+=' AtOM:OR ' "$destdir/$destfile.$extension" \
commandline+="cp -a \"$sourcepath/$filename\" \"$destdir/$destfile\"" 2>/dev/null \
copytaskid=$( || cp -a \
Insert tasks <<-EOInsert "$sourcepath/$filename" \
key ${fileid}copy$destination "$destdir/$destfile.$extension"
source_file $fileid echo \
command_line $commandline "UPDATE destination_files" \
status 0 "SET filename=\"${filename//\"/\"\"}\"," \
EOInsert " last_change=(" \
) " SELECT last_change" \
progressSpin " FROM source_files" \
" WHERE id=$fileid" \
" )" \
"WHERE id=$destfileid;" \
>&3
(( ++copies ))
} }
sanitizeFile() { sanitizeFile() {
string="$1" string="$1"
# Filenames can't contain / # Filenames can't contain /
string="${strings//\// }" string="${string//\// }"
if (( ${destinationfat32compat[$destination]} )) if (( ${destinationfat32compat[$destination]} ))
then then
# Filenames can't contain: # Filenames can't contain:
@ -1117,13 +1135,13 @@ getDestFile() {
} }
encodeFile::mp3() { encodeFile::mp3() {
lameopts="--quiet -v --abr ${destinationquality[$destination]}" lameopts=(lame --quiet -v --abr ${destinationquality[$destination]})
[ -n "$album" ] && lameopts+=" --tl \"$album\"" [ -n "$album" ] && lameopts+=(--tl "$album" )
[ -n "$artist" ] && lameopts+=" --ta \"$artist\"" [ -n "$artist" ] && lameopts+=(--ta "$artist")
[ -n "$genre" ] && lameopts+=" --tg \"$genre\"" [ -n "$genre" ] && lameopts+=(--tg "$genre")
[ -n "$title" ] && lameopts+=" --tt \"$title\"" [ -n "$title" ] && lameopts+=(--tt "$title")
[ -n "$track" ] && lameopts+=" --tn \"$track\"" [ -n "$track" ] && lameopts+=(--tn "$track")
[ -n "$year" ] && lameopts+=" --ty \"$year\"" [ -n "$year" ] && lameopts+=(--ty "$year")
if (( ${destinationnoresample[$destination]:-0} == 1 )) if (( ${destinationnoresample[$destination]:-0} == 1 ))
then then
# If 'rate' is not one of these value, it cannot be encoded to # If 'rate' is not one of these value, it cannot be encoded to
@ -1132,30 +1150,31 @@ encodeFile::mp3() {
if [ -n "${destinationfrequency["$destination"]}" ] if [ -n "${destinationfrequency["$destination"]}" ]
then then
case ${destinationfrequency["$destination"]} in case ${destinationfrequency["$destination"]} in
48000) lameopts+=" --resample 48" ;; 48000) lameopts+=(--resample 48) ;;
44100) lameopts+=" --resample 44.1" ;; 44100) lameopts+=(--resample 44.1) ;;
32000) lameopts+=" --resample 32" ;; 32000) lameopts+=(--resample 32) ;;
24000) lameopts+=" --resample 24" ;; 24000) lameopts+=(--resample 24) ;;
22050) lameopts+=" --resample 22.05" ;; 22050) lameopts+=(--resample 22.05) ;;
16000) lameopts+=" --resample 16" ;; 16000) lameopts+=(--resample 16) ;;
12000) lameopts+=" --resample 12" ;; 12000) lameopts+=(--resample 12) ;;
11025) lameopts+=" --resample 11.025" ;; 11025) lameopts+=(--resample 11.025) ;;
8000) lameopts+=" --resample 8" ;; 8000) lameopts+=(--resample 8) ;;
esac esac
else else
case $rate in case $rate in
48000) lameopts+=" --resample 48" ;; 48000) lameopts+=(--resample 48) ;;
44100) lameopts+=" --resample 44.1" ;; 44100) lameopts+=(--resample 44.1) ;;
32000) lameopts+=" --resample 32" ;; 32000) lameopts+=(--resample 32) ;;
24000) lameopts+=" --resample 24" ;; 24000) lameopts+=(--resample 24) ;;
22050) lameopts+=" --resample 22.05" ;; 22050) lameopts+=(--resample 22.05) ;;
16000) lameopts+=" --resample 16" ;; 16000) lameopts+=(--resample 16) ;;
12000) lameopts+=" --resample 12" ;; 12000) lameopts+=(--resample 12) ;;
11025) lameopts+=" --resample 11.025" ;; 11025) lameopts+=(--resample 11.025) ;;
8000) lameopts+=" --resample 8" ;; 8000) lameopts+=(--resample 8) ;;
esac esac
fi fi
fi fi
lameopts+=("$tempdir/$tmpfile.wav" "$destdir/$destfile.mp3")
encodetaskid=$( encodetaskid=$(
Insert tasks <<-EOInsert Insert tasks <<-EOInsert
key ${fileid}lame$destination key ${fileid}lame$destination
@ -1163,8 +1182,13 @@ encodeFile::mp3() {
required ${soxtaskid:-$decodetaskid} required ${soxtaskid:-$decodetaskid}
fileid $destfileid fileid $destfileid
filename $destdir/$destfile.mp3 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 source_file $fileid
status 0 status 0
EOInsert EOInsert
@ -1173,17 +1197,18 @@ encodeFile::mp3() {
} }
encodeFile::vorbis() { encodeFile::vorbis() {
oggencopts="-Q -q ${destinationquality[$destination]}" oggencopts=(oggenc -Q -q ${destinationquality[$destination]})
[ -n "$albumartist" ] && oggencopts+=" -c \"ALBUMARTIST=$albumartist\"" [ -n "$albumartist" ] && oggencopts+=(-c "ALBUMARTIST=$albumartist")
[ -n "$album" ] && oggencopts+=" -l \"$album\"" [ -n "$album" ] && oggencopts+=(-l "$album")
[ -n "$artist" ] && oggencopts+=" -a \"$artist\"" [ -n "$artist" ] && oggencopts+=(-a "$artist")
[ -n "$composer" ] && oggencopts+=" -c \"COMPOSER=$composer\"" [ -n "$composer" ] && oggencopts+=(-c "COMPOSER=$composer")
[ -n "$disc" ] && oggencopts+=" -c \"DISCNUMBER=$disc\"" [ -n "$disc" ] && oggencopts+=(-c "DISCNUMBER=$disc")
[ -n "$genre" ] && oggencopts+=" -G \"$genre\"" [ -n "$genre" ] && oggencopts+=(-G "$genre")
[ -n "$performer" ] && oggencopts+=" -c \"PERFORMER=$performer\"" [ -n "$performer" ] && oggencopts+=(-c "PERFORMER=$performer")
[ -n "$title" ] && oggencopts+=" -t \"$title\"" [ -n "$title" ] && oggencopts+=(-t "$title")
[ -n "$track" ] && oggencopts+=" -N \"$track\"" [ -n "$track" ] && oggencopts+=(-N "$track")
[ -n "$year" ] && oggencopts+=" -d \"$year\"" [ -n "$year" ] && oggencopts+=(-d "$year")
oggencopts+=(-o "$destdir/$destfile.ogg" "$tempdir/$tmpfile.wav")
encodetaskid=$( encodetaskid=$(
Insert tasks <<-EOInsert Insert tasks <<-EOInsert
key ${fileid}oggenc$destination key ${fileid}oggenc$destination
@ -1191,8 +1216,13 @@ encodeFile::vorbis() {
required ${soxtaskid:-$decodetaskid} required ${soxtaskid:-$decodetaskid}
fileid $destfileid fileid $destfileid
filename $destdir/$destfile.ogg 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 source_file $fileid
status 0 status 0
EOInsert EOInsert
@ -1254,7 +1284,65 @@ worker() {
rest=${rest#*|} rest=${rest#*|}
required=${rest%%|*} required=${rest%%|*}
rest=${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#*|} rest=${rest#*|}
cleanup=${rest%%|*} cleanup=${rest%%|*}
rest=${rest#*|} rest=${rest#*|}
@ -1262,7 +1350,12 @@ worker() {
rest=${rest#*|} rest=${rest#*|}
destfilename=${rest%%|*} destfilename=${rest%%|*}
rest=${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 then
echo "finished $taskid|$sourcefileid|$destfileid|$destfilename" echo "finished $taskid|$sourcefileid|$destfileid|$destfilename"
else else
@ -1270,6 +1363,7 @@ worker() {
[ -n "$filename" ] \ [ -n "$filename" ] \
&& eval rm -f $filename && eval rm -f $filename
fi fi
unset cmd_arg
if [ -n "$cleanup" -a -n "$required" ] if [ -n "$cleanup" -a -n "$required" ]
then then
echo "cleanup $required" echo "cleanup $required"
@ -1320,7 +1414,36 @@ master() {
id, id,
source_file, source_file,
required, 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, cleanup,
fileid, fileid,
filename filename
@ -1597,7 +1720,36 @@ echo '
source_file INTEGER, source_file INTEGER,
fileid INTEGER, fileid INTEGER,
filename TEXT, 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, requires INTEGER,
required INTEGER, required INTEGER,
status INTEGER NOT NULL, status INTEGER NOT NULL,
@ -1795,7 +1947,7 @@ do
tmpfile tmpfile
done done
echo 'COMMIT;' >&3 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* rm -f "$tempdir"/worker*
concurrency=$(( maxload / 2 )) concurrency=$(( maxload / 2 ))