Skip to content

Commit 177a655

Browse files
rf232eldering
authored andcommitted
Added support for public sample testcases.
Contestants can view testcases marked as sample as well as their program output on these cases. WARNING: this can and will leak information about the problem like timelimit and more.
1 parent 1749d77 commit 177a655

File tree

5 files changed

+105
-7
lines changed

5 files changed

+105
-7
lines changed

sql/mysql_db_structure.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,7 @@ CREATE TABLE `testcase` (
358358
`probid` varchar(8) NOT NULL COMMENT 'Corresponding problem ID',
359359
`rank` int(4) NOT NULL COMMENT 'Determines order of the testcases in judging',
360360
`description` varchar(255) default NULL COMMENT 'Description of this testcase',
361+
`sample` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT 'Sample testcases can be shared with teams.',
361362
PRIMARY KEY (`testcaseid`),
362363
UNIQUE KEY `rank` (`probid`,`rank`),
363364
KEY `probid` (`probid`),

sql/upgrade/upgrade_to-online_judge.sql

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,16 @@
88
--
99

1010
-- @UPGRADE-CHECK@
11-
SELECT 1;
11+
ALTER TABLE `testcase` ADD COLUMN `sample` tinyint(1) default NULL;
12+
ALTER TABLE `testcase` DROP COLUMN `sample`;
1213

1314
--
1415
-- Create additional structures
1516
--
1617

18+
ALTER TABLE `testcase`
19+
ADD COLUMN `sample` tinyint(1) unsigned NOT NULL default '0' COMMENT 'Sample testcases can be shared with teams.' AFTER `description`;
20+
1721
--
1822
-- Transfer data from old to new structure
1923
--

www/js/domjudge.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,31 @@ function hideTcDescEdit(descid)
6262
node.parentNode.appendChild(span);
6363
}
6464

65+
// make corresponding testcase sample dropdown editable
66+
function editTcSample(tcid)
67+
{
68+
var node = document.getElementById('sample_' + tcid + '_');
69+
node.parentNode.setAttribute('onclick', '');
70+
var remove = node.nextSibling;
71+
while (remove.nodeName == '#text')
72+
remove = remove.nextSibling;
73+
node.parentNode.removeChild(remove);
74+
node.style.display = 'block';
75+
node.setAttribute('name', 'sample[' + tcid + ']');
76+
}
77+
78+
// hides sample dropdown field if javascript is enabled
79+
function hideTcSample(tcid, str)
80+
{
81+
var node = document.getElementById('sample_' + tcid + '_');
82+
node.style.display = 'none';
83+
node.setAttribute('name', 'invalid');
84+
85+
var span = document.createElement('span');
86+
span.innerHTML = str;
87+
node.parentNode.appendChild(span);
88+
}
89+
6590
// Autodetection of problem, language in websubmit
6691
function detectProblemLanguage(filename)
6792
{

www/jury/testcase.php

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,14 @@
128128
}
129129
}
130130

131+
if ( isset($_POST['sample'][$rank]) ) {
132+
$DB->q('UPDATE testcase SET sample = %i WHERE probid = %s
133+
AND rank = %i', $_POST['sample'][$rank], $probid, $rank);
134+
$result .= "<li>Set testcase $rank to be " .
135+
($_POST['sample'][$rank] ? "" : "not ") .
136+
"a sample testcase</li>\n";
137+
}
138+
131139
if ( isset($_POST['description'][$rank]) ) {
132140
$DB->q('UPDATE testcase SET description = %s WHERE probid = %s
133141
AND rank = %i', $_POST['description'][$rank], $probid, $rank);
@@ -154,10 +162,11 @@
154162

155163
if ( !empty($content['input']) && !empty($content['output']) ) {
156164
$DB->q("INSERT INTO testcase
157-
(probid,rank,md5sum_input,md5sum_output,input,output,description)
158-
VALUES (%s,%i,%s,%s,%s,%s,%s)",
165+
(probid,rank,md5sum_input,md5sum_output,input,output,description,sample)
166+
VALUES (%s,%i,%s,%s,%s,%s,%s,%i)",
159167
$probid, $rank, md5(@$content['input']), md5(@$content['output']),
160-
@$content['input'], @$content['output'], @$_POST['add_desc']);
168+
@$content['input'], @$content['output'], @$_POST['add_desc'],
169+
@$_POST['add_sample']);
161170
auditlog('testcase', $probid, 'added', "rank $rank");
162171

163172
$result .= "<li>Added new testcase $rank from " .
@@ -172,7 +181,8 @@
172181
echo "<ul>\n$result</ul>\n\n";
173182

174183
// Reload testcase data after updates
175-
$data = $DB->q('KEYTABLE SELECT rank AS ARRAYKEY, testcaseid, rank, description,
184+
$data = $DB->q('KEYTABLE SELECT rank AS ARRAYKEY, testcaseid, rank,
185+
description, sample,
176186
OCTET_LENGTH(input) AS size_input, md5sum_input,
177187
OCTET_LENGTH(output) AS size_output, md5sum_output
178188
FROM testcase WHERE probid = %s ORDER BY rank', $probid);
@@ -196,7 +206,7 @@
196206
<th scope="col">size</th><th scope="col">md5</th>
197207
<?php
198208
if ( IS_ADMIN ) echo '<th scope="col">upload new</th>';
199-
?><th scope="col">description</th>
209+
?><th scope="col">sample</th><th scope="col">description</th>
200210
</tr></thead>
201211
<tbody>
202212
<?php
@@ -222,6 +232,12 @@
222232
}
223233
if ( $inout=='input' ) {
224234
if ( IS_ADMIN ) {
235+
echo "<td rowspan=\"2\" align=\"center]\" onclick=\"editTcSample($rank)\">" .
236+
addSelect("sample[$rank]",array("no", "yes"), $row['sample'], true) . "</td>";
237+
238+
// hide sample dropdown field if javascript is enabled
239+
echo "<script type=\"text/javascript\" language=\"JavaScript\">" .
240+
"hideTcSample($rank, '". printyn($row['sample'])."');</script>";
225241
echo "<td rowspan=\"2\" class=\"testdesc\" onclick=\"editTcDesc($rank)\">" .
226242
"<textarea id=\"tcdesc_$rank\" name=\"description[$rank]\" cols=\"50\" rows=\"2\">" .
227243
htmlspecialchars($row['description']) . "</textarea></td>" .
@@ -235,6 +251,8 @@
235251
echo "<script type=\"text/javascript\" language=\"JavaScript\">" .
236252
"hideTcDescEdit($rank);</script>";
237253
} else {
254+
echo "<td rowspan=\"2\" align=\"center\">" .
255+
printyn($row['issample']) . "</td>";
238256
echo "<td rowspan=\"2\" class=\"testdesc\">" .
239257
htmlspecialchars($row['description']) . "</td>";
240258
}
@@ -252,6 +270,7 @@
252270
<table>
253271
<tr><td>Input testdata: </td><td><?php echo addFileField('add_input') ?></td></tr>
254272
<tr><td>Output testdata:</td><td><?php echo addFileField('add_output') ?></td></tr>
273+
<tr><td>Sample testcase:</td><td><?php echo addSelect('add_sample', array("no","yes"), 0, true);?></td></tr>
255274
<tr><td>Description: </td><td><?php echo addInput('add_desc','',30); ?></td></tr>
256275
</table>
257276
<?php

www/team/submission_details.php

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
// select also on teamid so we can only select our own submissions
1717
$row = $DB->q('MAYBETUPLE SELECT p.probid, p.name AS probname, submittime,
18-
s.valid, l.name AS langname, result, output_compile, verified
18+
s.valid, l.name AS langname, result, output_compile, verified, judgingid
1919
FROM judging j
2020
LEFT JOIN submission s USING (submitid)
2121
LEFT JOIN language l USING (langid)
@@ -75,4 +75,53 @@
7575
echo "<p class=\"nodata\">Compilation output is disabled.</p>\n";
7676
}
7777

78+
if ( @$row['result']!='compiler-error' ) {
79+
$runs = $DB->q('SELECT r.*, t.rank, t.description FROM testcase t
80+
LEFT JOIN judging_run r ON ( r.testcaseid = t.testcaseid AND
81+
r.judgingid = %i )
82+
WHERE t.probid = %s AND t.sample = 1 ORDER BY rank',
83+
$row['judgingid'], $row['probid']);
84+
85+
$runinfo = $runs->gettable();
86+
echo '<h3>Run(s) on the provided sample data</h3>';
87+
88+
foreach ( $runinfo as $run ) {
89+
echo "<h4 id=\"run-$run[rank]\">Run $run[rank]</h4>\n\n";
90+
if ( $run['runresult']===NULL ) {
91+
echo "<p class=\"nodata\">Run not finished yet.</p>\n";
92+
continue;
93+
}
94+
echo "<table>\n" .
95+
"<tr><td>Description:</td><td>" .
96+
htmlspecialchars($run['description']) . "</td></tr>" .
97+
"<tr><td>Runtime:</td><td>$run[runtime] sec</td></tr>" .
98+
"<tr><td>Result: </td><td><span class=\"sol sol_" .
99+
( $run['runresult']=='correct' ? '' : 'in' ) .
100+
"correct\">$run[runresult]</span></td></tr>" .
101+
"</table>\n\n";
102+
echo "<h5>Program output</h5>\n";
103+
if ( @$run['output_run'] ) {
104+
echo "<pre class=\"output_text\">".
105+
htmlspecialchars($run['output_run'])."</pre>\n\n";
106+
} else {
107+
echo "<p class=\"nodata\">There was no program output.</p>\n";
108+
}
109+
echo "<h5>Diff output</h5>\n";
110+
if ( @$run['output_diff'] ) {
111+
echo "<pre class=\"output_text\">";
112+
echo parseDiff($run['output_diff']);
113+
echo "</pre>\n\n";
114+
} else {
115+
echo "<p class=\"nodata\">There was no diff output.</p>\n";
116+
}
117+
echo "<h5>Error output (info/debug/errors)</h5>\n";
118+
if ( @$run['output_error'] ) {
119+
echo "<pre class=\"output_text\">".
120+
htmlspecialchars($run['output_error'])."</pre>\n\n";
121+
} else {
122+
echo "<p class=\"nodata\">There was no stderr output.</p>\n";
123+
}
124+
}
125+
}
126+
78127
require(LIBWWWDIR . '/footer.php');

0 commit comments

Comments
 (0)