diff --git a/doc/040_cvarlist.md b/doc/040_cvarlist.md index f7d0cceb..fae8283b 100644 --- a/doc/040_cvarlist.md +++ b/doc/040_cvarlist.md @@ -114,8 +114,8 @@ it's `+set busywait 0` (setting the `busywait` cvar) and `-portable` `cl_http_bw_limit_tmout` variable. Set `0` by default. * **cl_http_bw_limit_tmout**: Seconds before the download is aborted -when the speed transfer is below the var set by `cl_http_bw_limit_rate`. -Set `0` by default. + when the speed transfer is below the var set by + `cl_http_bw_limit_rate`. Set `0` by default. * **cl_kickangles**: If set to `0` angle kicks (weapon recoil, damage hits and the like) are ignored. Cheat-protected. Defaults to `1`. @@ -138,8 +138,17 @@ Set `0` by default. loading. If set to `0` pause mode is never entered, this is the Vanilla Quake II behaviour. -* **cl_unpaused_scvis**: If set to `1` (the default) the client unpause - when the screen becomes visible. +* **cl_model_preview_start**: Start frame value in multiplayer model + preview. `-1` - don't show animation. Defaults to `84` for show + salute animation. + +* **cl_model_preview_end**: End frame value in multiplayer model + preview. `-1` - don't show animation. Defaults to `94` for show + salute animation. + +* **cl_nodownload_list**: Whitespace seperated list of strings, files + having one these strings in their name are never downloaded. Set to + `.dll .dylib .so` by default. * **cl_r1q2_lightstyle**: Since the first release Yamagi Quake II used the R1Q2 colors for the dynamic lights of rockets. Set to `0` to get @@ -153,11 +162,8 @@ Set `0` by default. the top right corner of the screen. Set to `2` to show only the horizontal speed under the crosshair. -* **cl_model_preview_start**: start frame value in multiplayer model preview. - `-1` - don't show animation. Defaults to `84` for show salute animation. - -* **cl_model_preview_end**: end frame value in multiplayer model preview. - `-1` - don't show animation. Defaults to `94` for show salute animation. +* **cl_unpaused_scvis**: If set to `1` (the default) the client unpause + when the screen becomes visible. * **in_grab**: Defines how the mouse is grabbed by Yamagi Quake IIs window. If set to `0` the mouse is never grabbed and if set to `1` diff --git a/doc/060_multiplayer.md b/doc/060_multiplayer.md index 3344111d..36ce2125 100644 --- a/doc/060_multiplayer.md +++ b/doc/060_multiplayer.md @@ -23,10 +23,10 @@ Apart from this, we'll only document changes/additions here. Quake II was released in 1997 into a world where security didn't matter. The most important thing when connecting to random servers is: **Quake II allows the server to do anything on the client!** The server may -execute any console command, it may overwrite any cvar and given the -rather fragile state of the command parsers chances are high that there -are remote code execution vulnerabilities. Only connect to trustworthy -servers! +execute any console command, it may overwrite any cvar, download any +file to your computer and given the rather fragile state of the command +parsers chances are high that there are remote code execution +vulnerabilities. Only connect to trustworthy servers! diff --git a/src/client/cl_download.c b/src/client/cl_download.c index 8dff62d4..328b8096 100644 --- a/src/client/cl_download.c +++ b/src/client/cl_download.c @@ -569,6 +569,17 @@ CL_CheckOrDownloadFile(const char *filename) return true; } + char *nodownload = strtok(cl_nodownload_list->string, " "); + while (nodownload != NULL) + { + if (Q_strcasestr(filename, nodownload)) + { + Com_Printf("Filename is filtered by cl_nodownload_list: %s\n", filename); + return true; + } + nodownload = strtok(NULL, " "); + } + #ifdef USE_CURL if (!forceudp) { diff --git a/src/client/cl_main.c b/src/client/cl_main.c index 38a41728..ecb58acc 100644 --- a/src/client/cl_main.c +++ b/src/client/cl_main.c @@ -51,6 +51,7 @@ cvar_t *cl_add_entities; cvar_t *cl_add_blend; cvar_t *cl_kickangles; cvar_t *cl_laseralpha; +cvar_t *cl_nodownload_list; cvar_t *cl_shownet; cvar_t *cl_showmiss; @@ -519,6 +520,7 @@ CL_InitLocal(void) cl_showfps = Cvar_Get("cl_showfps", "0", CVAR_ARCHIVE); cl_showspeed = Cvar_Get("cl_showspeed", "0", CVAR_ARCHIVE); cl_laseralpha = Cvar_Get("cl_laseralpha", "0.3", 0); + cl_nodownload_list = Cvar_Get("cl_nodownload_list", ".dll .dylib .so", 0); cl_upspeed = Cvar_Get("cl_upspeed", "200", 0); cl_forwardspeed = Cvar_Get("cl_forwardspeed", "200", 0); diff --git a/src/client/curl/qcurl.c b/src/client/curl/qcurl.c index b611091a..6f627553 100644 --- a/src/client/curl/qcurl.c +++ b/src/client/curl/qcurl.c @@ -101,6 +101,11 @@ qboolean qcurlInit(void) // Mkay, let's try to find a working libcurl. cl_libcurl = Cvar_Get("cl_libcurl", (char *)libcurl[0], CVAR_ARCHIVE); + if (strstr(cl_libcurl->string, "..") || strstr(cl_libcurl->string, ":") || strstr(cl_libcurl->string, "/") || strstr(cl_libcurl->string, "\\")) + { + Com_Printf("cl_libcurl must not contain '..', ':', '/' or '\': %s\n", cl_libcurl->string); + goto error; + } Com_Printf("Loading library: %s\n", cl_libcurl->string); Sys_LoadLibrary(cl_libcurl->string, NULL, &curlhandle); diff --git a/src/client/header/client.h b/src/client/header/client.h index a42aa24b..adfbf219 100644 --- a/src/client/header/client.h +++ b/src/client/header/client.h @@ -317,6 +317,7 @@ extern cvar_t *cl_kickangles; extern cvar_t *cl_r1q2_lightstyle; extern cvar_t *cl_limitsparksounds; extern cvar_t *cl_laseralpha; +extern cvar_t *cl_nodownload_list; typedef struct { diff --git a/src/client/sound/qal.c b/src/client/sound/qal.c index d856c342..da8cb16c 100644 --- a/src/client/sound/qal.c +++ b/src/client/sound/qal.c @@ -406,9 +406,14 @@ QAL_Init() /* DEFAULT_OPENAL_DRIVER is defined at compile time via the compiler */ al_driver = Cvar_Get("al_driver", DEFAULT_OPENAL_DRIVER, CVAR_ARCHIVE); - Com_Printf("Loading library: %s\n", al_driver->string); + if (strstr(al_driver->string, "..") || strstr(al_driver->string, ":") || strstr(al_driver->string, "/") || strstr(al_driver->string, "\\")) + { + Com_Printf("al_driver must not contain '..', ':', '/' or '\': %s\n", al_driver->string); + return false; + } /* Load the library */ + Com_Printf("Loading library: %s\n", al_driver->string); Sys_LoadLibrary(al_driver->string, NULL, &handle); if (!handle) diff --git a/src/common/header/shared.h b/src/common/header/shared.h index e05b1ec5..d6e9ecc7 100644 --- a/src/common/header/shared.h +++ b/src/common/header/shared.h @@ -325,6 +325,7 @@ void Com_PageInMemory(const byte *buffer, int size); int Q_stricmp(const char *s1, const char *s2); int Q_strcasecmp(const char *s1, const char *s2); int Q_strncasecmp(const char *s1, const char *s2, int n); +char *Q_strcasestr(const char *s1, const char *s2); /* portable string lowercase */ char *Q_strlwr(char *s); diff --git a/src/common/shared/shared.c b/src/common/shared/shared.c index 20e4ec7a..b208957c 100644 --- a/src/common/shared/shared.c +++ b/src/common/shared/shared.c @@ -1064,6 +1064,20 @@ Q_strncasecmp(const char *s1, const char *s2, int n) return 0; /* strings are equal */ } +char *Q_strcasestr(const char *haystack, const char *needle) +{ + size_t len = strlen(needle); + + for (; *haystack; haystack++) + { + if (!Q_strncasecmp(haystack, needle, len)) + { + return (char *)haystack; + } + } + return 0; +} + int Q_strcasecmp(const char *s1, const char *s2) {