4 Commits

Author SHA1 Message Date
copilot-swe-agent[bot]
80b77808f3 Fix OS command injection in fix_filename() - use allowlist for safe chars
Agent-Logs-Url: https://github.com/tbamud/tbamud/sessions/a9e10199-b353-440a-ba26-279f0d0e42bf

Co-authored-by: welcor <357770+welcor@users.noreply.github.com>
2026-04-24 10:22:33 +00:00
copilot-swe-agent[bot]
c5bed0e141 Initial plan 2026-04-24 10:16:38 +00:00
Copilot
87c75da59c Improve error message detail for wdoor/mdoor/odoor invalid args (#178) 2026-04-23 22:52:52 +02:00
Copilot
ac94839eb5 Add Unity-based unit test infrastructure (Phase 1 — 117 tests) (#177)
Introduced new system for unit tests based on the Unity framework.

Added tests for some of the simple functions in four different files.
2026-04-23 01:17:48 +02:00
5 changed files with 66 additions and 31 deletions

View File

@@ -3,7 +3,7 @@ name: C/C++ CI
on: on:
push: push:
branches: [ "master" ] branches: [ "master" ]
pull_request: pull_request_target:
branches: [ "master" ] branches: [ "master" ]
permissions: permissions:

View File

@@ -1024,17 +1024,27 @@ ACMD(do_mdoor)
} }
if ((rm = get_room(target)) == NULL) { if ((rm = get_room(target)) == NULL) {
mob_log(ch, "mdoor: invalid target"); mob_log(ch, "mdoor: invalid target (arg == %s)", target);
return; return;
} }
if ((dir = search_block(direction, dirs, FALSE)) == -1) { if ((dir = search_block(direction, dirs, FALSE)) == -1) {
mob_log(ch, "mdoor: invalid direction"); char dirs_str[256];
int di, doff = 0;
dirs_str[0] = '\0';
for (di = 0; *dirs[di] != '\n'; di++)
doff += snprintf(dirs_str + doff, sizeof(dirs_str) - doff, "%s%s", doff ? " " : "", dirs[di]);
mob_log(ch, "mdoor: invalid direction (arg == %s) not found in: [ %s ]", direction, dirs_str);
return; return;
} }
if ((fd = search_block(field, door_field, FALSE)) == -1) { if ((fd = search_block(field, door_field, FALSE)) == -1) {
mob_log(ch, "odoor: invalid field"); char fields_str[256];
int fi, foff = 0;
fields_str[0] = '\0';
for (fi = 0; *door_field[fi] != '\n'; fi++)
foff += snprintf(fields_str + foff, sizeof(fields_str) - foff, "%s%s", foff ? " " : "", door_field[fi]);
mob_log(ch, "mdoor: invalid field (arg == %s) not found in: [ %s ]", field, fields_str);
return; return;
} }
@@ -1081,8 +1091,10 @@ ACMD(do_mdoor)
case 5: /* room */ case 5: /* room */
if ((to_room = real_room(atoi(value))) != NOWHERE) if ((to_room = real_room(atoi(value))) != NOWHERE)
newexit->to_room = to_room; newexit->to_room = to_room;
else else {
mob_log(ch, "mdoor: invalid door target"); newexit->to_room = NOWHERE;
mob_log(ch, "mdoor: invalid door target (arg == %s)", value);
}
break; break;
} }
} }

View File

@@ -625,17 +625,27 @@ static OCMD(do_odoor)
} }
if ((rm = get_room(target)) == NULL) { if ((rm = get_room(target)) == NULL) {
obj_log(obj, "odoor: invalid target"); obj_log(obj, "odoor: invalid target (arg == %s)", target);
return; return;
} }
if ((dir = search_block(direction, dirs, FALSE)) == -1) { if ((dir = search_block(direction, dirs, FALSE)) == -1) {
obj_log(obj, "odoor: invalid direction"); char dirs_str[256];
int di, doff = 0;
dirs_str[0] = '\0';
for (di = 0; *dirs[di] != '\n'; di++)
doff += snprintf(dirs_str + doff, sizeof(dirs_str) - doff, "%s%s", doff ? " " : "", dirs[di]);
obj_log(obj, "odoor: invalid direction (arg == %s) not found in: [ %s ]", direction, dirs_str);
return; return;
} }
if ((fd = search_block(field, door_field, FALSE)) == -1) { if ((fd = search_block(field, door_field, FALSE)) == -1) {
obj_log(obj, "odoor: invalid field"); char fields_str[256];
int fi, foff = 0;
fields_str[0] = '\0';
for (fi = 0; *door_field[fi] != '\n'; fi++)
foff += snprintf(fields_str + foff, sizeof(fields_str) - foff, "%s%s", foff ? " " : "", door_field[fi]);
obj_log(obj, "odoor: invalid field (arg == %s) not found in: [ %s ]", field, fields_str);
return; return;
} }
@@ -682,8 +692,10 @@ static OCMD(do_odoor)
case 5: /* room */ case 5: /* room */
if ((to_room = real_room(atoi(value))) != NOWHERE) if ((to_room = real_room(atoi(value))) != NOWHERE)
newexit->to_room = to_room; newexit->to_room = to_room;
else else {
obj_log(obj, "odoor: invalid door target"); newexit->to_room = NOWHERE;
obj_log(obj, "odoor: invalid door target (arg == %s)", value);
}
break; break;
} }
} }

View File

@@ -224,17 +224,27 @@ WCMD(do_wdoor)
} }
if ((rm = get_room(target)) == NULL) { if ((rm = get_room(target)) == NULL) {
wld_log(room, "wdoor: invalid target"); wld_log(room, "wdoor: invalid target (arg == %s)", target);
return; return;
} }
if ((dir = search_block(direction, dirs, FALSE)) == -1) { if ((dir = search_block(direction, dirs, FALSE)) == -1) {
wld_log(room, "wdoor: invalid direction"); char dirs_str[256];
int di, doff = 0;
dirs_str[0] = '\0';
for (di = 0; *dirs[di] != '\n'; di++)
doff += snprintf(dirs_str + doff, sizeof(dirs_str) - doff, "%s%s", doff ? " " : "", dirs[di]);
wld_log(room, "wdoor: invalid direction (arg == %s) not found in: [ %s ]", direction, dirs_str);
return; return;
} }
if ((fd = search_block(field, door_field, FALSE)) == -1) { if ((fd = search_block(field, door_field, FALSE)) == -1) {
wld_log(room, "wdoor: invalid field"); char fields_str[256];
int fi, foff = 0;
fields_str[0] = '\0';
for (fi = 0; *door_field[fi] != '\n'; fi++)
foff += snprintf(fields_str + foff, sizeof(fields_str) - foff, "%s%s", foff ? " " : "", door_field[fi]);
wld_log(room, "wdoor: invalid field (arg == %s) not found in: [ %s ]", field, fields_str);
return; return;
} }
@@ -281,8 +291,10 @@ WCMD(do_wdoor)
case 5: /* room */ case 5: /* room */
if ((to_room = real_room(atoi(value))) != NOWHERE) if ((to_room = real_room(atoi(value))) != NOWHERE)
newexit->to_room = to_room; newexit->to_room = to_room;
else else {
wld_log(room, "wdoor: invalid door target"); newexit->to_room = NOWHERE;
wld_log(room, "wdoor: invalid door target (arg == %s)", value);
}
break; break;
} }
} }

View File

@@ -277,7 +277,10 @@ int sprintascii(char *out, bitvector_t bits)
return j; return j;
} }
/* converts illegal filename chars into appropriate equivalents */ /* converts illegal filename chars into appropriate equivalents.
* Uses an allowlist: alphanumerics, underscore, hyphen, and dot are kept;
* spaces are converted to underscores; all other characters (including shell
* metacharacters such as ; | & ` $ > < \n) are silently dropped. */
static void fix_filename(const char *str, char *outbuf, size_t maxlen) static void fix_filename(const char *str, char *outbuf, size_t maxlen)
{ {
const char *in = str; const char *in = str;
@@ -285,21 +288,17 @@ static void fix_filename(const char *str, char *outbuf, size_t maxlen)
int count = 0; int count = 0;
while (*in) { while (*in) {
switch(*in) { if (isalnum((unsigned char)*in) || *in == '_' || *in == '-' || *in == '.') {
case ' ': *out = '_'; out++; break; /* Safe characters kept as-is */
case '(': *out = '{'; out++; break; *out++ = *in;
case ')': *out = '}'; out++; break; if (++count == maxlen - 1) break;
} else if (*in == ' ') {
/* skip the following */ /* Spaces become underscores */
case '\'': break; *out++ = '_';
case '"': break; if (++count == maxlen - 1) break;
}
/* Legal character */ /* All other characters, including shell metacharacters, are dropped */
default: *out = *in; out++;break;
}
in++; in++;
count++;
if (count == maxlen - 1) break;
} }
*out = '\0'; *out = '\0';
} }