Index: openacs-4/packages/acs-templating/tcl/file-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-templating/tcl/file-procs.tcl,v diff -u -r1.12.2.6 -r1.12.2.7 --- openacs-4/packages/acs-templating/tcl/file-procs.tcl 24 Aug 2022 08:58:59 -0000 1.12.2.6 +++ openacs-4/packages/acs-templating/tcl/file-procs.tcl 25 Aug 2022 11:34:50 -0000 1.12.2.7 @@ -25,63 +25,104 @@ @return the list { file_name temp_file_name content_mime_type }. } { + # + # Check if these have already been converted, then return them as they are. + # + # This may happen, for instance, during the 'preview' action of a form. + # if { [ns_queryget $element_id.tmpfile] eq "" } { - # - # Ignore files when no tmpfiles are sent in the request: we - # can only trust tmpfiles generated by the server. - # - return [list] - } elseif {[ns_info name] eq "NaviServer"} { - # - # NaviServer - # - # Get the files information using 'ns_querygetall' - # - set filenames [ns_querygetall $element_id] - set tmpfiles [ns_querygetall $element_id.tmpfile] - set types [ns_querygetall $element_id.content-type] + set files [ns_querygetall $element_id] } else { + if {[ns_info name] eq "NaviServer"} { + # + # NaviServer + # + # Get the files information using 'ns_querygetall' + # + set filenames [ns_querygetall $element_id] + set tmpfiles [ns_querygetall $element_id.tmpfile] + set types [ns_querygetall $element_id.content-type] + } else { + # + # AOLserver + # + # ns_querygetall behaves differently in AOLserver, using the ns_queryget + # legacy version instead + # + set filenames [ns_queryget $element_id] + set tmpfiles [ns_queryget $element_id.tmpfile] + set types [ns_queryget $element_id.content-type] + } # - # AOLserver + # No files, get out # - # ns_querygetall behaves differently in AOLserver, using the ns_queryget - # legacy version instead + if {$filenames eq ""} { + return "" + } # - set filenames [ns_queryget $element_id] - set tmpfiles [ns_queryget $element_id.tmpfile] - set types [ns_queryget $element_id.content-type] - } - - # - # Return the files info in a list per file - # - set files [list] - for {set file 0} {$file < [llength $filenames]} {incr file} { - set filename [lindex $filenames $file] - set tmpfile [lindex $tmpfiles $file] - set type [lindex $types $file] + # Return the files info in a list per file # - # Cleanup filenames - # - regsub -all -- {\\+} $filename {/} filename - regsub -all -- { +} $filename {_} filename - set filename [lindex [split $filename "/"] end] - # - # Append to the list of lists - # - lappend files [list $filename $tmpfile $type] + set files [list] + for {set file 0} {$file < [llength $filenames]} {incr file} { + set filename [lindex $filenames $file] + set tmpfile [lindex $tmpfiles $file] + set type [lindex $types $file] + # + # Cleanup filenames + # + regsub -all -- {\\+} $filename {/} filename + regsub -all -- { +} $filename {_} filename + set filename [lindex [split $filename "/"] end] + # + # Append to the list of lists + # + lappend files [list $filename $tmpfile $type] + } } return $files } ad_proc -public template::data::validate::file { value_ref message_ref } { - Our file widget can't fail + Validate the values in the file widget. In particular: + - make sure values are a list of lists of 3 elements + - ensure character cleanup has been performed + - ensure tmpfiles are safe - @return true + @return boolean } { - return 1 + upvar 2 $message_ref message $value_ref value element element + + set result 1 + + if { ![::string is list $value] || + [llength $value] != 3 || + "" in $value + } { + # + # Value is not a list of 3 non-empty elements. + # + set result 0 + } elseif { [regexp {(\\| )} [lindex $value 0]] } { + # + # Backslashes and spaces were supposedly cleaned up during + # file_transform. + # + set result 0 + } elseif { ![security::safe_tmpfile_p [lindex $value 1]] } { + # + # The tmpfile is not safe + # + set result 0 + } + + if { !$result } { + set message [_ acs-templating.Invalid_file] + ad_log warning "They tried to sneak in invalid value '$value'" + } + + return $result } ad_proc -public template::util::file::get_property {