| 1 | ################################################################################ |
1 | ################################################################################ |
| 2 | # WeBWorK Online Homework Delivery System |
2 | # WeBWorK Online Homework Delivery System |
| 3 | # Copyright © 2000-2006 The WeBWorK Project, http://openwebwork.sf.net/ |
3 | # Copyright © 2000-2006 The WeBWorK Project, http://openwebwork.sf.net/ |
| 4 | # $CVSHeader: webwork2/lib/WeBWorK/ContentGenerator/Instructor/PGProblemEditor.pm,v 1.71 2006/01/11 23:08:44 dpvc Exp $ |
4 | # $CVSHeader: webwork2/lib/WeBWorK/ContentGenerator/Instructor/PGProblemEditor.pm,v 1.72 2006/01/25 23:13:53 sh002i Exp $ |
| 5 | # |
5 | # |
| 6 | # This program is free software; you can redistribute it and/or modify it under |
6 | # This program is free software; you can redistribute it and/or modify it under |
| 7 | # the terms of either: (a) the GNU General Public License as published by the |
7 | # the terms of either: (a) the GNU General Public License as published by the |
| 8 | # Free Software Foundation; either version 2, or (at your option) any later |
8 | # Free Software Foundation; either version 2, or (at your option) any later |
| 9 | # version, or (b) the "Artistic License" which comes with this package. |
9 | # version, or (b) the "Artistic License" which comes with this package. |
| … | |
… | |
| 26 | =cut |
26 | =cut |
| 27 | |
27 | |
| 28 | use strict; |
28 | use strict; |
| 29 | use warnings; |
29 | use warnings; |
| 30 | use CGI qw(); |
30 | use CGI qw(); |
| 31 | use WeBWorK::Utils qw(readFile surePathToFile); |
31 | use WeBWorK::Utils qw(readFile surePathToFile path_is_subdir); |
| 32 | use Apache::Constants qw(:common REDIRECT); |
32 | use Apache::Constants qw(:common REDIRECT); |
| 33 | use HTML::Entities; |
33 | use HTML::Entities; |
| 34 | use URI::Escape; |
34 | use URI::Escape; |
| 35 | use WeBWorK::Utils; |
35 | use WeBWorK::Utils; |
| 36 | use WeBWorK::Utils::Tasks qw(fake_set fake_problem); |
36 | use WeBWorK::Utils::Tasks qw(fake_set fake_problem); |
| … | |
… | |
| 472 | |
472 | |
| 473 | my $problemContents = ${$self->{r_problemContents}}; |
473 | my $problemContents = ${$self->{r_problemContents}}; |
| 474 | |
474 | |
| 475 | unless ( $problemContents =~/\S/) { # non-empty contents |
475 | unless ( $problemContents =~/\S/) { # non-empty contents |
| 476 | if (-r $tempFilePath and not -d $tempFilePath) { |
476 | if (-r $tempFilePath and not -d $tempFilePath) { |
|
|
477 | die "tempFilePath is unsafe!" unless path_is_subdir($tempFilePath, $ce->{courseDirs}->{templates}, 1); # 1==path can be relative to dir |
| 477 | eval { $problemContents = WeBWorK::Utils::readFile($tempFilePath) }; |
478 | eval { $problemContents = WeBWorK::Utils::readFile($tempFilePath) }; |
| 478 | $problemContents = $@ if $@; |
479 | $problemContents = $@ if $@; |
| 479 | $inputFilePath = $tempFilePath; |
480 | $inputFilePath = $tempFilePath; |
| 480 | } elsif (-r $editFilePath and not -d $editFilePath) { |
481 | } elsif (-r $editFilePath and not -d $editFilePath) { |
|
|
482 | die "editFilePath is unsafe!" unless path_is_subdir($editFilePath, $ce->{courseDirs}->{templates}, 1); # 1==path can be relative to dir |
| 481 | eval { $problemContents = WeBWorK::Utils::readFile($editFilePath) }; |
483 | eval { $problemContents = WeBWorK::Utils::readFile($editFilePath) }; |
| 482 | $problemContents = $@ if $@; |
484 | $problemContents = $@ if $@; |
| 483 | $inputFilePath = $editFilePath; |
485 | $inputFilePath = $editFilePath; |
| 484 | } else { # file not existing is not an error |
486 | } else { # file not existing is not an error |
| 485 | #warn "No file exists"; |
487 | #warn "No file exists"; |
| … | |
… | |
| 954 | #$problemContents =~ s/\r/\n/g; |
956 | #$problemContents =~ s/\r/\n/g; |
| 955 | |
957 | |
| 956 | # make sure any missing directories are created |
958 | # make sure any missing directories are created |
| 957 | WeBWorK::Utils::surePathToFile($ce->{courseDirs}->{templates}, |
959 | WeBWorK::Utils::surePathToFile($ce->{courseDirs}->{templates}, |
| 958 | $outputFilePath); |
960 | $outputFilePath); |
|
|
961 | die "outputFilePath is unsafe!" unless path_is_subdir($outputFilePath, $ce->{courseDirs}->{templates}, 1); # 1==path can be relative to dir |
| 959 | |
962 | |
| 960 | eval { |
963 | eval { |
| 961 | local *OUTPUTFILE; |
964 | local *OUTPUTFILE; |
| 962 | open OUTPUTFILE, ">$outputFilePath" |
965 | open OUTPUTFILE, ">$outputFilePath" |
| 963 | or die "Failed to open $outputFilePath"; |
966 | or die "Failed to open $outputFilePath"; |
| … | |
… | |
| 1003 | unless( $writeFileErrors or $do_not_save) { # everything worked! unlink and announce success! |
1006 | unless( $writeFileErrors or $do_not_save) { # everything worked! unlink and announce success! |
| 1004 | # unlink the temporary file if there are no errors and the save button has been pushed |
1007 | # unlink the temporary file if there are no errors and the save button has been pushed |
| 1005 | if (($action eq 'save' or $action eq 'save_as') and (-w $self->{tempFilePath}) ) { |
1008 | if (($action eq 'save' or $action eq 'save_as') and (-w $self->{tempFilePath}) ) { |
| 1006 | |
1009 | |
| 1007 | $self->addgoodmessage("Deleting temp file at " . $self->shortPath($self->{tempFilePath})); |
1010 | $self->addgoodmessage("Deleting temp file at " . $self->shortPath($self->{tempFilePath})); |
|
|
1011 | die "tempFilePath is unsafe!" unless path_is_subdir($self->{tempFilePath}, $ce->{courseDirs}->{templates}, 1); # 1==path can be relative to dir |
| 1008 | unlink($self->{tempFilePath}) ; |
1012 | unlink($self->{tempFilePath}) ; |
| 1009 | } |
1013 | } |
| 1010 | |
1014 | |
| 1011 | if ( defined($outputFilePath) and ! $self->{failure} and not $self->isTempEditFilePath($outputFilePath) ) { |
1015 | if ( defined($outputFilePath) and ! $self->{failure} and not $self->isTempEditFilePath($outputFilePath) ) { |
| 1012 | # don't announce saving of temporary editing files |
1016 | # don't announce saving of temporary editing files |
| … | |
… | |
| 1669 | return "Revert to ".$self->shortPath($editFilePath) ; |
1673 | return "Revert to ".$self->shortPath($editFilePath) ; |
| 1670 | |
1674 | |
| 1671 | } |
1675 | } |
| 1672 | sub revert_handler { |
1676 | sub revert_handler { |
| 1673 | my ($self, $genericParams, $actionParams, $tableParams) = @_; |
1677 | my ($self, $genericParams, $actionParams, $tableParams) = @_; |
|
|
1678 | my $ce = $self->ce; |
| 1674 | #$self->addgoodmessage("revert_handler called"); |
1679 | #$self->addgoodmessage("revert_handler called"); |
| 1675 | my $editFilePath = $self->{editFilePath}; |
1680 | my $editFilePath = $self->{editFilePath}; |
| 1676 | $self->{inputFilePath} = $editFilePath; |
1681 | $self->{inputFilePath} = $editFilePath; |
| 1677 | # unlink the temp files; |
1682 | # unlink the temp files; |
|
|
1683 | die "tempFilePath is unsafe!" unless path_is_subdir($self->{tempFilePath}, $ce->{courseDirs}->{templates}, 1); # 1==path can be relative to dir |
| 1678 | unlink($self->{tempFilePath}); |
1684 | unlink($self->{tempFilePath}); |
| 1679 | $self->addgoodmessage("Deleting temp file at " . $self->shortPath($self->{tempFilePath})); |
1685 | $self->addgoodmessage("Deleting temp file at " . $self->shortPath($self->{tempFilePath})); |
| 1680 | $self->{tempFilePath} = ''; |
1686 | $self->{tempFilePath} = ''; |
| 1681 | my $problemContents =''; |
1687 | my $problemContents =''; |
| 1682 | $self->{r_problemContents} = \$problemContents; |
1688 | $self->{r_problemContents} = \$problemContents; |