diff --git a/lib/new_server_html.c b/lib/new_server_html.c
index 5849efefa..722dbff6a 100644
--- a/lib/new_server_html.c
+++ b/lib/new_server_html.c
@@ -13968,7 +13968,7 @@ unpriv_submit_run(
const struct section_global_data *global = cs->global;
const struct section_problem_data *prob = 0, *prob2;
const struct section_language_data *lang = 0;
- int prob_id, n, lang_id = 0, i, ans, max_ans, j, r;
+ int prob_id = 0, n, lang_id = 0, i, ans, max_ans, j, r;
const unsigned char *s, *run_text = 0, *text_form_text = 0;
size_t run_size = 0, ans_size, text_form_size = 0;
unsigned char *ans_buf, *ans_map, *ans_tmp;
@@ -13999,10 +13999,30 @@ unpriv_submit_run(
l10n_setlocale(phr->locale_id);
- if (hr_cgi_param(phr, "prob_id", &s) <= 0
- || sscanf(s, "%d%n", &prob_id, &n) != 1 || s[n]
- || prob_id <= 0 || prob_id > cs->max_prob
- || !(prob = cs->probs[prob_id])) {
+ if (hr_cgi_param(phr, "prob_id", &s) <= 0) {
+ FAIL2(NEW_SRV_ERR_INV_PROB_ID);
+ }
+ prob_id = 0;
+ {
+ errno = 0;
+ char *ep = NULL;
+ long v = strtol(s, &ep, 10);
+ if (!errno && !*ep && ep != (const char *) s && v > 0 && v < cs->max_prob && cs->probs[v]) {
+ prob_id = v;
+ prob = cs->probs[prob_id];
+ }
+ }
+ if (!prob) {
+ for (int pid = 1; pid <= cs->max_prob; ++pid) {
+ const struct section_problem_data *pp = cs->probs[pid];
+ if (pp && !strcmp(pp->short_name, s)) {
+ prob = pp;
+ prob_id = pid;
+ break;
+ }
+ }
+ }
+ if (!prob) {
FAIL2(NEW_SRV_ERR_INV_PROB_ID);
}