From c927b2e8349042d4a08f9bb6657f72ccb6ef9274 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 20 Aug 2002 06:11:10 +0000 Subject: [PATCH] quakefs.c: allow . and .. in a path so long as the result doesn't escape from the game directory cl_menu/Makefile.am: don't strip source paths optoins.qc: use InputLine object def.c: use notice to show stray temps emit.c: make sure expression args get emitted for function calls expr.c: 'C' is a cast rewrite cast_expr to handle casted pointere derefs --- libs/util/quakefs.c | 83 ++++++++++++++++++++++++++++++------- ruamoko/cl_menu/Makefile.am | 4 +- ruamoko/cl_menu/options.qc | 47 ++++++++++----------- tools/qfcc/source/def.c | 21 ++++++---- tools/qfcc/source/emit.c | 2 +- tools/qfcc/source/expr.c | 24 ++++++----- 6 files changed, 122 insertions(+), 59 deletions(-) diff --git a/libs/util/quakefs.c b/libs/util/quakefs.c index bfd6fb6cc..23da38e3f 100644 --- a/libs/util/quakefs.c +++ b/libs/util/quakefs.c @@ -362,6 +362,56 @@ COM_OpenRead (const char *path, int offs, int len, int zip) return Qdopen (fd, "rb"); } +char * +COM_CompressPath (const char *pth) +{ + char *path= malloc (strlen (pth) + 1); + char *p, *d; + + for (d = path; *pth; d++, pth++) { + if (*pth == '\\') + *d = '/'; + else + *d = *pth; + } + *d = 0; + + p = path; + while (*p) { + if (p[0] == '.') { + if (p[1] == '.') { + if (p[2] == '/' || p[2] == 0) { + d = p; + if (d > path) + d--; + while (d > path && d[-1] != '/') + d--; + if (d == path + && d[0] == '.' && d[1] == '.' + && (d[2] == '/' || d[2] == '0')) { + p += 2 + (p[2] == '/'); + continue; + } + strcpy (d, p + 2 + (p[2] == '/')); + p = d; + continue; + } + } else if (p[1] == '/') { + strcpy (p, p + 2); + continue; + } else if (p[1] == 0) { + p[0] = 0; + } + } + while (*p && *p != '/') + p++; + if (*p == '/') + p++; + } + + return path; +} + /* contains_updir @@ -444,6 +494,7 @@ int _COM_FOpenFile (const char *filename, VFile **gzfile, char *foundname, int zip) { searchpath_t *search; + char *path; #ifdef HAVE_VORBIS char oggfilename[MAX_OSPATH]; #endif @@ -451,9 +502,16 @@ _COM_FOpenFile (const char *filename, VFile **gzfile, char *foundname, int zip) char gzfilename[MAX_OSPATH]; #endif + // make sure they're not trying to do weird stuff with our private files + path = COM_CompressPath (filename); + if (contains_updir(path)) { + Sys_Printf ("FindFile: %s: attempt to escape directory tree!\n", path); + goto error; + } + #ifdef HAVE_VORBIS - if (strequal (".wav", COM_FileExtension (filename))) { - COM_StripExtension (filename, oggfilename); + if (strequal (".wav", COM_FileExtension (path))) { + COM_StripExtension (path, oggfilename); strncat (oggfilename, ".ogg", sizeof (oggfilename) - strlen (oggfilename) - 1); } else { @@ -461,36 +519,33 @@ _COM_FOpenFile (const char *filename, VFile **gzfile, char *foundname, int zip) } #endif #ifdef HAVE_ZLIB - snprintf (gzfilename, sizeof (gzfilename), "%s.gz", filename); + snprintf (gzfilename, sizeof (gzfilename), "%s.gz", path); #endif - // make sure they're not trying to do wierd stuff with our private files - if (contains_updir(filename)) { - Sys_Printf ("FindFile: %s: attempt to escape directory tree!\n", - filename); - goto error; - } - // search through the path, one element at a time for (search = com_searchpaths; search; search = search->next) { #ifdef HAVE_VORBIS if (oggfilename[0] && open_file (search, oggfilename, gzfile, foundname, zip) != -1) - return com_filesize; + goto ok; #endif #ifdef HAVE_ZLIB if (open_file (search, gzfilename, gzfile, foundname, zip) != -1) - return com_filesize; + goto ok; #endif - if (open_file (search, filename, gzfile, foundname, zip) != -1) - return com_filesize; + if (open_file (search, path, gzfile, foundname, zip) != -1) + goto ok; } Sys_DPrintf ("FindFile: can't find %s\n", filename); error: *gzfile = NULL; com_filesize = -1; + free (path); return -1; +ok: + free(path); + return com_filesize; } int diff --git a/ruamoko/cl_menu/Makefile.am b/ruamoko/cl_menu/Makefile.am index bdc3d4b2e..04546cc49 100644 --- a/ruamoko/cl_menu/Makefile.am +++ b/ruamoko/cl_menu/Makefile.am @@ -25,10 +25,10 @@ menu_src= \ options_util.qc servlist.qc string.r stringh.r %.qfo: %.r - $(QFCC) $(QCFLAGS) $(QCPPFLAGS) -p $(STRIP) -c -o $@ $< + $(QFCC) $(QCFLAGS) $(QCPPFLAGS) -c -o $@ $< %.qfo: %.qc - $(QFCC) $(QCFLAGS) $(QCPPFLAGS) -p $(STRIP) -c -o $@ $< + $(QFCC) $(QCFLAGS) $(QCPPFLAGS) -c -o $@ $< menu_obj=$(addsuffix .qfo,$(basename $(menu_src))) diff --git a/ruamoko/cl_menu/options.qc b/ruamoko/cl_menu/options.qc index 129c3615c..bf6e73fd1 100644 --- a/ruamoko/cl_menu/options.qc +++ b/ruamoko/cl_menu/options.qc @@ -454,11 +454,11 @@ string playername_cvar; // name of the cvar holding playername (gametype depende string teamname_cvar; // name of the cvar holding teamname (MAY ? gametype dependend) // input for playername and teamname -inputline_t player_config_plname_il; -inputline_t player_config_tname_il; +InputLine player_config_plname_il; +InputLine player_config_tname_il; // this holds active inputline pointer -inputline_t player_config_iactive; +InputLine player_config_iactive; // Y padding for the player config #define PLAYER_CONF_Y_PAD 60 @@ -506,9 +506,9 @@ KEYEV_player_options = case QFK_RETURN: if (player_config_iactive) { if(player_config_iactive == player_config_plname_il) { - cvar_set(playername_cvar,InputLine_GetText(player_config_plname_il)); + cvar_set(playername_cvar, [player_config_plname_il text]); } else if(player_config_iactive == player_config_tname_il) { - cvar_set(teamname_cvar,InputLine_GetText(player_config_tname_il)); + cvar_set(teamname_cvar, [player_config_tname_il text]); } player_config_iactive = NIL; } else { @@ -521,7 +521,7 @@ KEYEV_player_options = break; } if(key != QFK_RETURN && player_config_iactive) { - InputLine_Process (player_config_iactive, key >= 256 ? key : unicode); + [player_config_iactive processInput:(key >= 256 ? key : unicode)]; } if(!(key == QFK_RIGHT || key == QFK_LEFT )) { @@ -566,13 +566,11 @@ DRAW_player_options = Draw_String(70, PLAYER_CONF_Y_PAD + 8, "Name..:"); text_box(120, PLAYER_CONF_Y_PAD, 17, 1); - InputLine_Draw (player_config_plname_il, 120, PLAYER_CONF_Y_PAD + 8, - player_config_iactive == player_config_plname_il); + [player_config_plname_il draw: player_config_iactive == player_config_plname_il]; Draw_String(70, PLAYER_CONF_Y_PAD + 20 + 8, "Team..:"); text_box(120, PLAYER_CONF_Y_PAD + 20, 5, 1); - InputLine_Draw (player_config_tname_il, 120, PLAYER_CONF_Y_PAD + 8 + 20, - player_config_iactive == player_config_tname_il); + [player_config_tname_il draw:player_config_iactive == player_config_tname_il]; draw_val_item (70, PLAYER_CONF_Y_PAD + 45, spacing, "Top color", @@ -610,8 +608,8 @@ CB_ME_player_options = teamname_cvar = "team"; // FIXME: is this maybe something other in netquake? - InputLine_SetText (player_config_plname_il, Cvar_GetCvarString(playername_cvar)); - InputLine_SetText (player_config_tname_il, Cvar_GetCvarString(teamname_cvar)); + [player_config_plname_il setText:Cvar_GetCvarString(playername_cvar)]; + [player_config_tname_il setText:Cvar_GetCvarString(teamname_cvar)]; }; /* @@ -622,10 +620,10 @@ CB_ME_player_options = void () MENU_player_options = { - player_config_plname_il = InputLine_Create (4, 18, ' '); - InputLine_SetWidth (player_config_plname_il, 18); - player_config_tname_il = InputLine_Create (4, 7, ' '); - InputLine_SetWidth (player_config_tname_il, 7); + id (player_config_plname_il) = [[InputLine alloc] initWithBounds:[[Rect alloc] initWithComponents:120 :PLAYER_CONF_Y_PAD + 8 :18 :4] promptCharacter:' ']; + [player_config_plname_il setWidth:18]; + id (player_config_tname_il) = [[InputLine alloc] initWithBounds:[[Rect alloc] initWithComponents:120 :PLAYER_CONF_Y_PAD + 8 + 20 :7 :4] promptCharacter:' ']; + [player_config_tname_il setWidth:7]; player_config_iactive = NIL; Menu_Begin (54, 80, "Player"); @@ -642,9 +640,9 @@ MENU_player_options = ******************************************************************************/ // input for playername -inputline_t network_config_rate_il; +InputLine network_config_rate_il; // this holds active inputline pointer -inputline_t network_config_iactive; +InputLine network_config_iactive; integer network_config_cursor; @@ -687,7 +685,7 @@ KEYEV_network_options = case QFK_RETURN: if (network_config_iactive) { if(network_config_iactive == network_config_rate_il) { - cvar_set("rate",InputLine_GetText(network_config_rate_il)); + cvar_set("rate", [network_config_rate_il text]); } network_config_iactive = NIL; } else { @@ -698,7 +696,7 @@ KEYEV_network_options = break; } if(key != QFK_RETURN && network_config_iactive) { - InputLine_Process (network_config_iactive, key >= 256 ? key : unicode); + [network_config_iactive processInput:(key >= 256 ? key : unicode)]; } if(!(key == QFK_RIGHT || key == QFK_LEFT )) { @@ -731,8 +729,7 @@ DRAW_network_options = Draw_String(70, NETWORK_CONF_Y_PAD + 8, "Rate..:"); text_box(120, NETWORK_CONF_Y_PAD, 9, 1); - InputLine_Draw (network_config_rate_il, 120, NETWORK_CONF_Y_PAD + 8, - network_config_iactive == network_config_rate_il); + [network_config_rate_il draw: network_config_iactive == network_config_rate_il]; opt_cursor (62, player_config_cursor_tbl[player_config_cursor]); return 1; @@ -748,7 +745,7 @@ DRAW_network_options = integer () CB_ME_network_options = { - InputLine_SetText (network_config_rate_il, Cvar_GetCvarString("rate")); + [network_config_rate_il setText:Cvar_GetCvarString("rate")]; }; @@ -761,8 +758,8 @@ CB_ME_network_options = void () MENU_network_options = { - network_config_rate_il = InputLine_Create (4, 9, ' '); - InputLine_SetWidth (network_config_rate_il, 9); + id (network_config_rate_il) = [[InputLine alloc] initWithBounds:[[Rect alloc] initWithComponents: 120 :NETWORK_CONF_Y_PAD + 8 :9 :4] promptCharacter:' ']; + [network_config_rate_il setWidth:9]; Menu_Begin (54, 90, "Network"); Menu_FadeScreen (1); diff --git a/tools/qfcc/source/def.c b/tools/qfcc/source/def.c index c85528092..2476bd495 100644 --- a/tools/qfcc/source/def.c +++ b/tools/qfcc/source/def.c @@ -396,10 +396,13 @@ free_tempdefs (void) d = *def; *def = d->next; - if (d->users < 0) - printf ("%s:%d: warning: %s %3d %3d %d\n", G_GETSTR (d->file), - d->line, pr_type_name[d->type->type], d->ofs, d->users, - d->managed); + if (d->users < 0) { + expr_t e; + e.file = d->file; + e.line = d->line; + notice (&e, "%s %3d %3d %d", pr_type_name[d->type->type], + d->ofs, d->users, d->managed); + } size = type_size (d->type); if (d->expr) d->expr->e.temp.def = 0; @@ -425,9 +428,13 @@ reset_tempdefs (void) free_temps[i] = 0; } - for (d = temp_scope.next; d; d = d->next) - printf ("%s:%d: warning: %s %3d %3d %d\n", G_GETSTR (d->file), d->line, - pr_type_name[d->type->type], d->ofs, d->users, d->managed); + for (d = temp_scope.next; d; d = d->next) { + expr_t e; + e.file = d->file; + e.line = d->line; + notice (&e, "%s %3d %3d %d", pr_type_name[d->type->type], + d->ofs, d->users, d->managed); + } temp_scope.next = 0; } diff --git a/tools/qfcc/source/emit.c b/tools/qfcc/source/emit.c index 4eb829fa7..e06ba72f9 100644 --- a/tools/qfcc/source/emit.c +++ b/tools/qfcc/source/emit.c @@ -209,7 +209,7 @@ emit_function_call (expr_t *e, def_t *dest) parm = def_parms[ind]; parm.type = types[extract_type (earg)]; arg = emit_sub_expr (earg, &parm); - if (earg->type != ex_expr && earg->type != ex_uexpr) { + if (arg != &parm) { op = opcode_find ("=", arg, &parm, &def_void); emit_statement (e, op, arg, &parm, 0); } diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c index 829112b61..26fbc361e 100644 --- a/tools/qfcc/source/expr.c +++ b/tools/qfcc/source/expr.c @@ -342,6 +342,7 @@ get_op_string (int op) case 'b': return ""; case 's': return ""; case 'c': return ""; + case 'C': return ""; default: return "unknown"; } @@ -2053,18 +2054,21 @@ cast_expr (type_t *type, expr_t *e) e_type = get_type (e); - if (type->type == ev_pointer && e_type->type == ev_pointer) { - c = new_unary_expr ('C', e); - c->e.expr.type = type; - } else if (((type == &type_integer || type == &type_uinteger) - && e_type == &type_float) - || (type == &type_float - && (e_type == &type_integer || e_type == &type_uinteger))) { - c = new_unary_expr ('C', e); - c->e.expr.type = type; - } else { + if (!(type->type == ev_pointer && e_type->type == ev_pointer) + && !(((type == &type_integer || type == &type_uinteger) + && e_type == &type_float) + || (type == &type_float + && (e_type == &type_integer || e_type == &type_uinteger)))) { c = error (e, "can not cast from %s to %s", pr_type_name[extract_type (e)], pr_type_name[type->type]); + return c; + } + if (e->type == ex_uexpr && e->e.expr.op == '.') { + e->e.expr.type = type; + c = e; + } else { + c = new_unary_expr ('C', e); + c->e.expr.type = type; } return c; }