| … | |
… | |
| 14 | use strict; |
14 | use strict; |
| 15 | use warnings; |
15 | use warnings; |
| 16 | use WeBWorK::DB::Classlist; |
16 | use WeBWorK::DB::Classlist; |
| 17 | use WeBWorK::DB::WW; |
17 | use WeBWorK::DB::WW; |
| 18 | use WeBWorK::PG::Translator; |
18 | use WeBWorK::PG::Translator; |
|
|
19 | use WeBWorK::Problem; |
| 19 | use WeBWorK::Utils qw(readFile formatDateTime); |
20 | use WeBWorK::Utils qw(readFile formatDateTime); |
| 20 | |
21 | |
| 21 | sub new($$$$$$$$) { |
22 | sub new($$$$$$$$) { |
| 22 | my $invocant = shift; |
23 | my $invocant = shift; |
| 23 | my $class = ref($invocant) || $invocant; |
24 | my $class = ref($invocant) || $invocant; |
| … | |
… | |
| 36 | # get database information |
37 | # get database information |
| 37 | my $classlist = WeBWorK::DB::Classlist->new($courseEnv); |
38 | my $classlist = WeBWorK::DB::Classlist->new($courseEnv); |
| 38 | my $wwdb = WeBWorK::DB::WW->new($courseEnv); |
39 | my $wwdb = WeBWorK::DB::WW->new($courseEnv); |
| 39 | my $user = $classlist->getUser($userName); |
40 | my $user = $classlist->getUser($userName); |
| 40 | my $set = $wwdb->getSet($userName, $setName); |
41 | my $set = $wwdb->getSet($userName, $setName); |
| 41 | my $problem = $wwdb->getProblem($userName, $setName, $problemNumber); |
|
|
| 42 | my $psvn = $wwdb->getPSVN($userName, $setName); |
42 | my $psvn = $wwdb->getPSVN($userName, $setName); |
| 43 | |
43 | |
| 44 | # *** NOTE: in order to support set header files, I propose adding a |
44 | my $problem; |
| 45 | # magic problemNumber (i.e. 0 or -1) which would cuase $problem to |
45 | if ($problemNumber =~ /^\d+$/) { |
| 46 | # contain a dummy problem whose source file is the set header file. |
46 | $problem = $wwdb->getProblem($userName, $setName, $problemNumber); |
|
|
47 | } else { |
|
|
48 | # This is the fun part: if $problemNumber is NON-NUMERIC, the |
|
|
49 | # user wants to specify a PG file directly. We manufacture a |
|
|
50 | # Problem object using fake data and the specified source file. |
|
|
51 | # This is potentially dangerous since an untrusted user is |
|
|
52 | # allowed to specifiy an arbitrary file to be evaluated as PG. |
|
|
53 | # A user of PG.pm MUST MAKE SURE that if $problemNumber is |
|
|
54 | # supplied by an untrusted source (i.e. the Apache request), |
|
|
55 | # it is numberic. A simple |
|
|
56 | # |
|
|
57 | # die unless $problemNumber =~ /^\d+$/; |
|
|
58 | # |
|
|
59 | # should suffice. |
|
|
60 | $problem = WeBWorK::Problem->new( |
|
|
61 | id => 0, |
|
|
62 | set_id => $set->id, |
|
|
63 | login_id => $user->id, |
|
|
64 | source_file => $problemNumber, |
|
|
65 | # the rest of Problem's fields are not needed |
|
|
66 | ); |
|
|
67 | } |
| 47 | |
68 | |
| 48 | # create a Translator |
69 | # create a Translator |
| 49 | warn "PG: creating a Translator\n"; |
70 | warn "PG: creating a Translator\n"; |
| 50 | my $translator = WeBWorK::PG::Translator->new; |
71 | my $translator = WeBWorK::PG::Translator->new; |
| 51 | |
72 | |
| … | |
… | |
| 93 | warn "PG: setting the opcode mask (using default values)\n"; |
114 | warn "PG: setting the opcode mask (using default values)\n"; |
| 94 | $translator->set_mask(); |
115 | $translator->set_mask(); |
| 95 | |
116 | |
| 96 | # store the problem source |
117 | # store the problem source |
| 97 | warn "PG: storing the problem source\n"; |
118 | warn "PG: storing the problem source\n"; |
|
|
119 | my $sourceFile = $problem->source_file; |
| 98 | my $sourceFile = $courseEnv->{courseDirs}->{templates}."/".$problem->source_file; |
120 | $sourceFile = $courseEnv->{courseDirs}->{templates}."/".$sourceFile |
|
|
121 | unless ($sourceFile =~ /^\//); |
| 99 | $translator->source_string(readFile($sourceFile)); |
122 | $translator->source_string(readFile($sourceFile)); |
| 100 | |
123 | |
| 101 | # install a safety filter (&safetyFilter) |
124 | # install a safety filter (&safetyFilter) |
| 102 | warn "PG: installing a safety filter\n"; |
125 | warn "PG: installing a safety filter\n"; |
| 103 | $translator->rf_safety_filter(\&safetyFilter); |
126 | $translator->rf_safety_filter(\&safetyFilter); |