The crash of the day:

giving units names or descriptions that exceed NAMESIZE/DISPLAYSIZE can be a bad thing.
This commit is contained in:
Enno Rehling 2004-09-12 09:51:36 +00:00
parent 110198f684
commit dde02d16e7
3 changed files with 142 additions and 110 deletions

View File

@ -1368,96 +1368,6 @@ ally_cmd(unit * u, struct order * ord)
} }
return 0; return 0;
} }
/* ------------------------------------------------------------- */
static int
display_cmd(unit * u, struct order * ord)
{
char **s = NULL;
region * r = u->region;
init_tokens(ord);
skip_token();
switch (getparam(u->faction->locale)) {
case P_BUILDING:
case P_GEBAEUDE:
if (!u->building) {
cmistake(u, ord, 145, MSG_PRODUCE);
break;
}
if (!fval(u, UFL_OWNER)) {
cmistake(u, ord, 5, MSG_PRODUCE);
break;
}
if (u->building->type == bt_find("generic")) {
cmistake(u, ord, 279, MSG_PRODUCE);
break;
}
if (u->building->type == bt_find("monument") && u->building->display[0] != 0) {
cmistake(u, ord, 29, MSG_PRODUCE);
break;
}
if (u->building->type == bt_find("artsculpture") && u->building->display[0] != 0) {
cmistake(u, ord, 29, MSG_PRODUCE);
break;
}
s = &u->building->display;
break;
case P_SHIP:
if (!u->ship) {
cmistake(u, ord, 144, MSG_PRODUCE);
break;
}
if (!fval(u, UFL_OWNER)) {
cmistake(u, ord, 12, MSG_PRODUCE);
break;
}
s = &u->ship->display;
break;
case P_UNIT:
s = &u->display;
break;
case P_PRIVAT:
{
const char *d = getstrtoken();
if(d == NULL || *d == 0) {
usetprivate(u, NULL);
} else {
usetprivate(u, d);
}
}
break;
case P_REGION:
if (!u->building) {
cmistake(u, ord, 145, MSG_EVENT);
break;
}
if (!fval(u, UFL_OWNER)) {
cmistake(u, ord, 148, MSG_EVENT);
break;
}
if (u->building != largestbuilding(r,false)) {
cmistake(u, ord, 147, MSG_EVENT);
break;
}
s = &r->display;
break;
default:
cmistake(u, ord, 110, MSG_EVENT);
break;
}
if (!s) return 0;
set_string(&(*s), getstrtoken());
return 0;
}
static int static int
prefix_cmd(unit * u, struct order * ord) prefix_cmd(unit * u, struct order * ord)
@ -1547,18 +1457,112 @@ synonym_cmd(unit * u, struct order * ord)
return 0; return 0;
} }
static int
display_cmd(unit * u, struct order * ord)
{
char **s = NULL;
region * r = u->region;
init_tokens(ord);
skip_token();
switch (getparam(u->faction->locale)) {
case P_BUILDING:
case P_GEBAEUDE:
if (!u->building) {
cmistake(u, ord, 145, MSG_PRODUCE);
break;
}
if (!fval(u, UFL_OWNER)) {
cmistake(u, ord, 5, MSG_PRODUCE);
break;
}
if (u->building->type == bt_find("generic")) {
cmistake(u, ord, 279, MSG_PRODUCE);
break;
}
if (u->building->type == bt_find("monument") && u->building->display[0] != 0) {
cmistake(u, ord, 29, MSG_PRODUCE);
break;
}
if (u->building->type == bt_find("artsculpture") && u->building->display[0] != 0) {
cmistake(u, ord, 29, MSG_PRODUCE);
break;
}
s = &u->building->display;
break;
case P_SHIP:
if (!u->ship) {
cmistake(u, ord, 144, MSG_PRODUCE);
break;
}
if (!fval(u, UFL_OWNER)) {
cmistake(u, ord, 12, MSG_PRODUCE);
break;
}
s = &u->ship->display;
break;
case P_UNIT:
s = &u->display;
break;
case P_PRIVAT:
{
const char *d = getstrtoken();
if(d == NULL || *d == 0) {
usetprivate(u, NULL);
} else {
usetprivate(u, d);
}
}
break;
case P_REGION:
if (!u->building) {
cmistake(u, ord, 145, MSG_EVENT);
break;
}
if (!fval(u, UFL_OWNER)) {
cmistake(u, ord, 148, MSG_EVENT);
break;
}
if (u->building != largestbuilding(r,false)) {
cmistake(u, ord, 147, MSG_EVENT);
break;
}
s = &r->display;
break;
default:
cmistake(u, ord, 110, MSG_EVENT);
break;
}
if (s!=NULL) {
const char * s2 = getstrtoken();
if (strlen(s2)>=DISPLAYSIZE) {
char * s3 = strdup(s2);
s3[DISPLAYSIZE] = 0;
set_string(s, s3);
free(s3);
} else
set_string(s, s2);
}
return 0;
}
static int static int
name_cmd(unit * u, struct order * ord) name_cmd(unit * u, struct order * ord)
{ {
region * r = u->region; region * r = u->region;
char **s; char **s = NULL;
const char *s2;
int i;
param_t p; param_t p;
boolean foreign = false; boolean foreign = false;
s = 0;
init_tokens(ord); init_tokens(ord);
skip_token(); skip_token();
p = getparam(u->faction->locale); p = getparam(u->faction->locale);
@ -1791,23 +1795,29 @@ name_cmd(unit * u, struct order * ord)
break; break;
} }
if (!s) return 0; if (s!=NULL) {
const char * s2 = getstrtoken();
s2 = getstrtoken(); if (!s2[0]) {
cmistake(u, ord, 84, MSG_EVENT);
return 0;
}
if (strchr(s2, '(')!=NULL) {
cmistake(u, ord, 112, MSG_EVENT);
return 0;
}
if (strlen(s2)>=NAMESIZE) {
char * s3 = strdup(s2);
s3[NAMESIZE] = 0;
set_string(s, s3);
free(s3);
} else
set_string(s, s2);
if (!s2[0]) {
cmistake(u, ord, 84, MSG_EVENT);
return 0;
} }
for (i = 0; s2[i]; i++)
if (s2[i] == '(')
break;
if (s2[i]) {
cmistake(u, ord, 112, MSG_EVENT);
return 0;
}
set_string(&(*s), s2);
return 0; return 0;
} }
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */

View File

@ -1026,7 +1026,11 @@ readunit(FILE * F)
if (f!=u->faction) u_setfaction(u, f); if (f!=u->faction) u_setfaction(u, f);
} }
rds(F, &u->name); rds(F, &u->name);
rds(F, &u->display); rds(F, &u->display);
#ifndef NDEBUG
if (strlen(u->name)>=NAMESIZE) u->name[NAMESIZE] = 0;
if (strlen(u->display)>=DISPLAYSIZE) u->name[DISPLAYSIZE] = 0;
#endif
number = ri(F); number = ri(F);
if (global.data_version<ITEMTYPE_VERSION) if (global.data_version<ITEMTYPE_VERSION)
set_money(u, ri(F)); set_money(u, ri(F));
@ -1270,6 +1274,9 @@ readregion(FILE * F, int x, int y)
if (landregion(rterrain(r))) { if (landregion(rterrain(r))) {
r->land = calloc(1, sizeof(land_region)); r->land = calloc(1, sizeof(land_region));
rds(F, &r->land->name); rds(F, &r->land->name);
#ifndef NDEBUG
if (strlen(r->land->name)>=NAMESIZE) r->land->name[NAMESIZE] = 0;
#endif
} }
if (r->land) { if (r->land) {
int i; int i;
@ -1518,10 +1525,14 @@ readfaction(FILE * F)
} }
rds(F, &f->name); rds(F, &f->name);
rds(F, &f->banner);
#ifndef NDEBUG
if (strlen(f->name)>=NAMESIZE) f->name[NAMESIZE] = 0;
if (strlen(f->banner)>=DISPLAYSIZE) f->banner[DISPLAYSIZE] = 0;
#endif
if (!quiet) printf(" - Lese Partei %s (%s)\n", f->name, factionid(f)); if (!quiet) printf(" - Lese Partei %s (%s)\n", f->name, factionid(f));
rds(F, &f->banner);
rds(F, &email); rds(F, &email);
if (set_email(&f->email, email)!=0) { if (set_email(&f->email, email)!=0) {
log_error(("Invalid email address for faction %s: %s\n", itoa36(f->no), email)); log_error(("Invalid email address for faction %s: %s\n", itoa36(f->no), email));
@ -1850,6 +1861,10 @@ readgame(const char * filename, int backup)
bhash(b); bhash(b);
rds(F, &b->name); rds(F, &b->name);
rds(F, &b->display); rds(F, &b->display);
#ifndef NDEBUG
if (strlen(b->name)>=NAMESIZE) b->name[NAMESIZE] = 0;
if (strlen(b->display)>=DISPLAYSIZE) b->name[DISPLAYSIZE] = 0;
#endif
b->size = ri(F); b->size = ri(F);
if (global.data_version < TYPES_VERSION) { if (global.data_version < TYPES_VERSION) {
assert(!"data format is no longer supported"); assert(!"data format is no longer supported");
@ -1876,6 +1891,10 @@ readgame(const char * filename, int backup)
shash(sh); shash(sh);
rds(F, &sh->name); rds(F, &sh->name);
rds(F, &sh->display); rds(F, &sh->display);
#ifndef NDEBUG
if (strlen(sh->name)>=NAMESIZE) sh->name[NAMESIZE] = 0;
if (strlen(sh->display)>=DISPLAYSIZE) sh->name[DISPLAYSIZE] = 0;
#endif
rs(F, buf); rs(F, buf);
sh->type = st_find(buf); sh->type = st_find(buf);

View File

@ -1,3 +1,6 @@
The crash of the day:
giving units names or descriptions that exceed NAMESIZE/DISPLAYSIZE can be a bad thing.
[11:01] <Enno`> am besten wäre, wenn mailit nur die optionen, nicht das ganze script enthielte [11:01] <Enno`> am besten wäre, wenn mailit nur die optionen, nicht das ganze script enthielte
[11:01] <Enno`> und ein skript dann mailit als input nähme [11:01] <Enno`> und ein skript dann mailit als input nähme
[11:02] <Enno`> also nur enno@eressea.upb.de pka3 BZIP2 nr cr zv [11:02] <Enno`> also nur enno@eressea.upb.de pka3 BZIP2 nr cr zv