diff --git a/src/common/gamecode/laws.c b/src/common/gamecode/laws.c index 06a696b21..eb37662e4 100644 --- a/src/common/gamecode/laws.c +++ b/src/common/gamecode/laws.c @@ -1368,96 +1368,6 @@ ally_cmd(unit * u, struct order * ord) } 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 prefix_cmd(unit * u, struct order * ord) @@ -1547,18 +1457,112 @@ synonym_cmd(unit * u, struct order * ord) 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 name_cmd(unit * u, struct order * ord) { region * r = u->region; - char **s; - const char *s2; - int i; + char **s = NULL; param_t p; boolean foreign = false; - s = 0; - init_tokens(ord); skip_token(); p = getparam(u->faction->locale); @@ -1791,23 +1795,29 @@ name_cmd(unit * u, struct order * ord) 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; } /* ------------------------------------------------------------- */ diff --git a/src/common/kernel/save.c b/src/common/kernel/save.c index 4ea1bc9fd..d4cba7f43 100644 --- a/src/common/kernel/save.c +++ b/src/common/kernel/save.c @@ -1026,7 +1026,11 @@ readunit(FILE * F) if (f!=u->faction) u_setfaction(u, f); } 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); if (global.data_versionland = calloc(1, sizeof(land_region)); rds(F, &r->land->name); +#ifndef NDEBUG + if (strlen(r->land->name)>=NAMESIZE) r->land->name[NAMESIZE] = 0; +#endif } if (r->land) { int i; @@ -1518,10 +1525,14 @@ readfaction(FILE * F) } 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)); - rds(F, &f->banner); rds(F, &email); if (set_email(&f->email, email)!=0) { 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); rds(F, &b->name); 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); if (global.data_version < TYPES_VERSION) { assert(!"data format is no longer supported"); @@ -1876,6 +1891,10 @@ readgame(const char * filename, int backup) shash(sh); rds(F, &sh->name); 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); sh->type = st_find(buf); diff --git a/src/todo.txt b/src/todo.txt index 227842b16..634f404fa 100644 --- a/src/todo.txt +++ b/src/todo.txt @@ -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] am besten wäre, wenn mailit nur die optionen, nicht das ganze script enthielte [11:01] und ein skript dann mailit als input nähme [11:02] also nur enno@eressea.upb.de pka3 BZIP2 nr cr zv