--- loncom/interface/loncommon.pm 2013/08/08 02:12:52 1.1075.2.43 +++ loncom/interface/loncommon.pm 2013/08/19 07:44:32 1.1075.2.47 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # a pile of common routines # -# $Id: loncommon.pm,v 1.1075.2.43 2013/08/08 02:12:52 raeburn Exp $ +# $Id: loncommon.pm,v 1.1075.2.47 2013/08/19 07:44:32 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -9850,16 +9850,16 @@ sub ask_for_embedded_content { $embed_file = $file; } my $absolutepath; - if ($embed_file =~ m{^\w+://}) { - $newfiles{$embed_file} = 1; - $mapping{$embed_file} = $embed_file; + my $cleaned_file = &clean_path($embed_file); + if ($cleaned_file =~ m{^\w+://}) { + $newfiles{$cleaned_file} = 1; + $mapping{$cleaned_file} = $embed_file; } else { if ($embed_file =~ m{^/}) { $absolutepath = $embed_file; - $embed_file =~ s{^(/+)}{}; } - if ($embed_file =~ m{/}) { - my ($path,$fname) = ($embed_file =~ m{^(.+)/([^/]*)$}); + if ($cleaned_file =~ m{/}) { + my ($path,$fname) = ($cleaned_file =~ m{^(.+)/([^/]*)$}); $path = &check_for_traversal($path,$url,$toplevel); my $item = $fname; if ($path ne '') { @@ -9876,9 +9876,9 @@ sub ask_for_embedded_content { } else { $dependencies{$embed_file} = 1; if ($absolutepath) { - $mapping{$embed_file} = $absolutepath; + $mapping{$cleaned_file} = $absolutepath; } else { - $mapping{$embed_file} = $embed_file; + $mapping{$cleaned_file} = $embed_file; } } } @@ -10252,6 +10252,47 @@ sub ask_for_embedded_content { return ($output,$counter,$numpathchg); } + +=pod + +=item * clean_path($name) + +Performs clean-up of directories, subdirectories and filename in an +embedded object, referenced in an HTML file which is being uploaded +to a course or portfolio, where +"Upload embedded images/multimedia files if HTML file" checkbox was +checked. + +Clean-up is similar to replacements in lonnet::clean_filename() +except each / between sub-directory and next level is preserved. + +=cut + +sub clean_path { + my ($embed_file) = @_; + $embed_file =~s{^/+}{}; + my @contents; + if ($embed_file =~ m{/}) { + @contents = split(/\//,$embed_file); + } else { + @contents = ($embed_file); + } + my $lastidx = scalar(@contents)-1; + for (my $i=0; $i<=$lastidx; $i++) { + $contents[$i]=~s{\\}{/}g; + $contents[$i]=~s/\s+/\_/g; + $contents[$i]=~s{[^/\w\.\-]}{}g; + if ($i == $lastidx) { + $contents[$i]=~s/\.(\d+)(?=\.)/_$1/g; + } + } + if ($lastidx > 0) { + return join('/',@contents); + } else { + return $contents[0]; + } +} + sub embedded_file_element { my ($context,$num,$embed_file,$mapping,$allfiles,$codebase,$type) = @_; return unless ((ref($mapping) eq 'HASH') && (ref($allfiles) eq 'HASH') && @@ -13095,18 +13136,22 @@ sub restore_settings { =item * &build_recipient_list() -Build recipient lists for five types of e-mail: +Build recipient lists for following types of e-mail: (a) Error Reports, (b) Package Updates, (c) lonstatus warnings/errors -(d) Help requests, (e) Course requests needing approval, generated by -lonerrorhandler.pm, CHECKRPMS, loncron, lonsupportreq.pm and -loncoursequeueadmin.pm respectively. +(d) Help requests, (e) Course requests needing approval, (f) loncapa +module change checking, student/employee ID conflict checks, as +generated by lonerrorhandler.pm, CHECKRPMS, loncron, +lonsupportreq.pm, loncoursequeueadmin.pm, searchcat.pl respectively. Inputs: -defmail (scalar - email address of default recipient), -mailing type (scalar - errormail, packagesmail, or helpdeskmail), +defmail (scalar - email address of default recipient), +mailing type (scalar: errormail, packagesmail, helpdeskmail, +requestsmail, updatesmail, or idconflictsmail). + defdom (domain for which to retrieve configuration settings), -origmail (scalar - email address of recipient from loncapa.conf, -i.e., predates configuration by DC via domainprefs.pm + +origmail (scalar - email address of recipient from loncapa.conf, +i.e., predates configuration by DC via domainprefs.pm Returns: comma separated list of addresses to which to send e-mail. @@ -13482,7 +13527,7 @@ sub assign_category_rows { if (ref($cats->[$depth]{$parent}) eq 'ARRAY') { my $numchildren = @{$cats->[$depth]{$parent}}; my $css_class = $itemcount%2?' class="LC_odd_row"':''; - $text .= ''; + $text .= '
'; for (my $j=0; $j<$numchildren; $j++) { $name = $cats->[$depth]{$parent}[$j]; $item = &escape($name).':'.&escape($parent).':'.$depth; @@ -14576,8 +14621,8 @@ sub recurse_supplemental { foreach my $res (@LONCAPA::map::resources) { my ($title,$src,$ext,$type,$status)=split(/\:/,$res); if (($src ne '') && ($status eq 'res')) { - if ($src =~ m{^\Q/uploaded/$cdom/$cnum/\E(supplemental_/d+\.sequence)$}) { - $numfiles = &recurse_supplemental($cnum,$cdom,$1,$numfiles); + if ($src =~ m{^\Q/uploaded/$cdom/$cnum/\E(supplemental_\d+\.sequence)$}) { + ($numfiles,$errors) = &recurse_supplemental($cnum,$cdom,$1,$numfiles,$errors); } else { $numfiles ++; } @@ -14618,7 +14663,7 @@ sub symb_to_docspath { my $thistitle = $res->title(); $path .= '&'. &Apache::lonhtmlcommon::entity_encode($thisurl).'&'. - &Apache::lonhtmlcommon::entity_encode($thistitle). + &escape($thistitle). ':'.$res->randompick(). ':'.$res->randomout(). ':'.$res->encrypted(). @@ -14634,7 +14679,7 @@ sub symb_to_docspath { } $path .= (($path ne '')? '&' : ''). &Apache::lonhtmlcommon::entity_encode($mapurl).'&'. - &Apache::lonhtmlcommon::entity_encode($maptitle). + &escape($maptitle). ':'.$mapresobj->randompick(). ':'.$mapresobj->randomout(). ':'.$mapresobj->encrypted(). @@ -14647,11 +14692,11 @@ sub symb_to_docspath { $maptitle = 'Main Content'; } $path = &Apache::lonhtmlcommon::entity_encode($mapurl).'&'. - &Apache::lonhtmlcommon::entity_encode($maptitle).':::::'.$ispage; + &escape($maptitle).':::::'.$ispage; } unless ($mapurl eq 'default') { $path = 'default&'. - &Apache::lonhtmlcommon::entity_encode('Main Content'). + &escape('Main Content'). ':::::&'.$path; } return $path;