Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ uudecode
serve-control
new-client
newrevinfo
lib_ut
ej-batch
ej-compile
ej-compile-control
Expand Down
4 changes: 4 additions & 0 deletions files.make
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ REUSE_CFILES=\
reuse/reuse_xstrmerge2.c\
reuse/reuse_xstrmerge3.c

COMMON_UT_CFILES=\
lib/serve_2_ut.c\
version.c

COMMON_CFILES=\
lib/agent_client_ssh.c\
lib/allowed_list.c\
Expand Down
32 changes: 19 additions & 13 deletions lib/serve_2.c
Original file line number Diff line number Diff line change
Expand Up @@ -1300,31 +1300,37 @@ serve_audit_log(
fclose(f);
}

static char **
static char*
env_for_lang(char* env, const char* lang)
{
size_t llen = strlen(lang);
if (!strncmp(env, lang, llen) && env[llen] == '=') {
return env + llen + 1;
}
return NULL;
}

char **
filter_lang_environ(
const struct ejudge_cfg *config,
serve_state_t state,
const struct section_problem_data *prob,
const struct section_language_data *lang,
const struct section_tester_data *tester,
char **environ)
{
int count = 0, i, llen, j = 0;
int count = 0, i, j = 0;
char **env = NULL;
llen = strlen(lang->short_name);
char *lang_env;
for (i = 0; environ[i]; ++i) {
if (environ[i][0] == '*' && environ[i][1] == '=') {
++count;
} else if (strlen(environ[i]) > llen && !strncmp(lang->short_name, environ[i], llen) && environ[i][llen] == '=') {
if (env_for_lang(environ[i], "*") || env_for_lang(environ[i], lang->short_name)) {
++count;
}
}
XCALLOC(env, count + 1);
for (i = 0; environ[i]; ++i) {
if (environ[i][0] == '*' && environ[i][1] == '=') {
env[j++] = prepare_varsubst(state, environ[i] + 2, 0, prob, lang, tester);
} else if (strlen(environ[i]) > llen && !strncmp(lang->short_name, environ[i], llen) && environ[i][llen] == '=') {
env[j++] = prepare_varsubst(state, environ[i] + llen + 1, 0, prob, lang, tester);
if ((lang_env = env_for_lang(environ[i], "*")) ||
(lang_env = env_for_lang(environ[i], lang->short_name))) {
env[j++] = prepare_varsubst(state, lang_env, 0, prob, lang, tester);
}
}
return env;
Expand Down Expand Up @@ -1475,10 +1481,10 @@ serve_compile_request(
}

if (prob && prob->lang_compiler_env && lang) {
comp_env_mem_2 = filter_lang_environ(config, state, prob, lang, NULL, prob->lang_compiler_env);
comp_env_mem_2 = filter_lang_environ(state, prob, lang, NULL, prob->lang_compiler_env);
}
if (prob && lang && prob->lang_compiler_container_options) {
compiler_container_options = filter_lang_environ(config, state, prob, lang, NULL, prob->lang_compiler_container_options);
compiler_container_options = filter_lang_environ(state, prob, lang, NULL, prob->lang_compiler_container_options);
}

if (compiler_env && compiler_env[0] && comp_env_mem_2 && comp_env_mem_2[0]) {
Expand Down
70 changes: 70 additions & 0 deletions lib/serve_2_ut.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#include <stdlib.h>
#include <check.h>

#include "ejudge/serve_state.h"
#include "ejudge/prepare.h"

char **
filter_lang_environ(
serve_state_t state,
const struct section_problem_data *prob,
const struct section_language_data *lang,
const struct section_tester_data *tester,
char **environ);

START_TEST(test_filter_env)
{
struct serve_state state = {0};
struct section_problem_data prob = {
.short_name = "collatz",
};
struct section_language_data lang = {
.short_name = "gcc-32",
};
struct section_tester_data tester = {0};
char *environ[] = {
"gcc-32=a=1",
"gcc=b=2",
"*=probname=${problem.short_name}",
NULL
};
char **newenv = filter_lang_environ(&state, &prob, &lang, &tester, environ);
ck_assert_str_eq(newenv[0], "a=1");
ck_assert_str_eq(newenv[1], "probname=collatz");
ck_assert(newenv[2] == NULL);
free(newenv[0]);
free(newenv[1]);
free(newenv);
}
END_TEST

Suite * serve_2_suite(void)
{
Suite *s;
TCase *tc_core;

s = suite_create("Serve_2");

/* Core test case */
tc_core = tcase_create("Core");

tcase_add_test(tc_core, test_filter_env);
suite_add_tcase(s, tc_core);

return s;
}

int main(void)
{
int number_failed;
Suite *s;
SRunner *sr;

s = serve_2_suite();
sr = srunner_create(s);

srunner_run_all(sr, CK_NORMAL);
number_failed = srunner_ntests_failed(sr);
srunner_free(sr);
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}
5 changes: 5 additions & 0 deletions main.unix.make
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ CC=gcc
LD=gcc
EXPAT_LIB=-lexpat

COMMON_UT_OBJECTS=$(COMMON_UT_CFILES:.c=.o) libcommon.a libuserlist_clnt.a libplatform.a libcommon.a

C_CFILES=bin/ej-compile.c version.c
C_OBJECTS=$(C_CFILES:.c=.o) libcommon.a libplatform.a libcommon.a

Expand Down Expand Up @@ -310,6 +312,9 @@ suid_install : ${SUIDBINTARGETS} ejudge-suid-setup ej-compile-control

suid_bins : ${SUIDBINTARGETS}

lib_ut$(EXESFX) : $(COMMON_UT_OBJECTS)
$(LD) $(LDFLAGS) $(COMMON_UT_OBJECTS) -o $@ -lcheck -lsubunit $(LDLIBS) ${EXPAT_LIB} ${LIBUUID}

ej-compile$(EXESFX) : $(C_OBJECTS)
$(LD) $(LDFLAGS) $(C_OBJECTS) -pthread -o $@ $(LDLIBS) ${EXPAT_LIB} ${LIBZIP} ${LIBUUID} ${LIBLZMA}

Expand Down