diff --git a/engine/Makefile b/engine/Makefile index 9cadbd8a8..667a0a07c 100644 --- a/engine/Makefile +++ b/engine/Makefile @@ -20,7 +20,7 @@ ifeq ($(SVNREVISION),) endif MAKE:=$(MAKE) SVNREVISION=$(SVNREVISION) -WHOAMI:=$(shell whoami) +#WHOAMI:=$(shell whoami) #update these to download+build a different version. this assumes that the url+subdirs etc contain a consistant version everywhere. @@ -28,7 +28,7 @@ JPEGVER=9b ZLIBVER=1.2.11 PNGVER=1.6.34 OGGVER=1.3.3 -VORBISVER=1.3.5 +VORBISVER=1.3.6 SDL2VER=2.0.7 SCINTILLAVER=373 OPUSVER=1.2.1 @@ -77,11 +77,14 @@ ifneq (,$(BRANDING)) BRANDFLAGS+=-DBRANDING_INC=../game_$(BRANDING).h -include game_$(BRANDING).mak endif -ifneq (,$(FTE_CONFIG)) - export FTE_CONFIG_EXTRA:=$(shell $(CC) -xc -E -P -DFTE_TARGET_$(FTE_TARGET) -DCOMPILE_OPTS common/config_$(FTE_CONFIG).h) - BRANDFLAGS+=-DCONFIG_FILE_NAME=config_$(FTE_CONFIG).h $(FTE_CONFIG_EXTRA) - EXE_NAME=$(FTE_CONFIG) +FTE_CONFIG?=fteqw +ifneq ($(FTE_TARGET),vc) +ifeq (,$(FTE_CONFIG_EXTRA)) + export FTE_CONFIG_EXTRA := $(shell $(CC) -xc -E -P -DFTE_TARGET_$(FTE_TARGET) -DCOMPILE_OPTS common/config_$(FTE_CONFIG).h) endif +endif +BRANDFLAGS+=-DCONFIG_FILE_NAME=config_$(FTE_CONFIG).h $(FTE_CONFIG_EXTRA) +EXE_NAME=$(FTE_CONFIG) ifeq (,$(findstring DNO_SPEEX,$(FTE_CONFIG_EXTRA))) USE_SPEEX=1 endif @@ -856,9 +859,9 @@ endif COMMONLIBFLAGS= COMMONLDDEPS= -CLIENTLIBFLAGS=$(COMMONLIBFLAGS) $(LIBOPUS_STATIC) $(LIBSPEEX_STATIC) $(OGGVORBISFILE_STATIC) $(LIBFREETYPE_STATIC) +CLIENTLIBFLAGS=$(COMMONLIBFLAGS) $(LIBOPUS_STATIC) $(LIBSPEEX_STATIC) $(OGGVORBISFILE_STATIC) SERVERLIBFLAGS=$(COMMONLIBFLAGS) -CLIENTLDDEPS=$(COMMONLDDEPS) $(LIBOPUS_LDFLAGS) $(LIBSPEEX_LDFLAGS) $(OGGVORBISLDFLAGS) $(LIBFREETYPE_LDFLAGS) +CLIENTLDDEPS=$(COMMONLDDEPS) $(LIBOPUS_LDFLAGS) $(LIBSPEEX_LDFLAGS) $(OGGVORBISLDFLAGS) SERVERLDDEPS=$(COMMONLDDEPS) ifeq (1,$(USE_OPUS)) LIBOPUS_STATIC=-DOPUS_STATIC @@ -877,12 +880,12 @@ else OGGVORBISFILE_STATIC= endif ifeq (1,$(LINK_FREETYPE)) - LIBFREETYPE_STATIC=-DFREETYPE_STATIC - LIBFREETYPE_LDFLAGS=-lfreetype + CLIENTLIBFLAGS+=-DFREETYPE_STATIC + CLIENTLDDEPS+=-lfreetype endif ifeq (1,$(LINK_PNG)) - LIBFREETYPE_STATIC=-DAVAIL_PNG - LIBFREETYPE_LDFLAGS=-lpng + CLIENTLIBFLAGS+=-DAVAIL_PNG + CLIENTLDDEPS+=-lpng endif ifeq (1,$(strip $(INTERNAL_BULLET))) COMMON_OBJS+=com_phys_bullet.o @@ -1739,6 +1742,7 @@ $(OUT_DIR)/%.mo $(OUT_DIR)/%.d : %.m $(OUT_DIR)/quakedef.h.gch : quakedef.h $(CC) -x c $(ALL_CFLAGS) -o $@ -c $< PRECOMPHEADERS ?= $(OUT_DIR)/quakedef.h.gch +ALL_CFLAGS+=-I$(OUT_DIR) #addprefix is to add the ./release/server/ part of the object name #foreach is needed as the OBJS is a list of variable names containing object lists. @@ -2201,7 +2205,7 @@ libs-$(ARCH)/libspeexdsp.a: libs-$(ARCH)/libfreetype.a: test -f freetype-$(FREETYPEVER).tar.gz || wget https://download.savannah.gnu.org/releases/freetype/freetype-$(FREETYPEVER).tar.gz - -test -f libs-$(ARCH)/libfreetype.a || (mkdir -p libs-$(ARCH) && cd libs-$(ARCH) && tar -xvzf ../freetype-$(FREETYPEVER).tar.gz && cd freetype-$(FREETYPEVER) && CFLAGS="$(CFLAGS) -Os" $(TOOLOVERRIDES) ./configure $(CONFIGARGS) && $(TOOLOVERRIDES) $(MAKE) && cp objs/.libs/libfreetype.a ../ && cp -r include/ ../) + -test -f libs-$(ARCH)/libfreetype.a || (mkdir -p libs-$(ARCH) && cd libs-$(ARCH) && tar -xvzf ../freetype-$(FREETYPEVER).tar.gz && cd freetype-$(FREETYPEVER) && CFLAGS="$(CFLAGS) -Os" $(TOOLOVERRIDES) ./configure $(CONFIGARGS) --with-harfbuzz=no && $(TOOLOVERRIDES) $(MAKE) && cp objs/.libs/libfreetype.a ../ && cp -r include/ ../) libs-$(ARCH)/libBulletDynamics.a: test -f bullet3-$(BULLETVER).tar.gz || wget https://github.com/bulletphysics/bullet3/archive/$(BULLETVER).tar.gz -O bullet3-$(BULLETVER).tar.gz diff --git a/engine/botlib/be_ai_chat.c b/engine/botlib/be_ai_chat.c index 8377aa6fe..6d222100a 100644 --- a/engine/botlib/be_ai_chat.c +++ b/engine/botlib/be_ai_chat.c @@ -342,7 +342,8 @@ void BotQueueConsoleMessage(int chatstate, int type, char *message) m->handle = cs->handle; m->time = AAS_Time(); m->type = type; - strncpy(m->message, message, MAX_MESSAGE_SIZE); + strncpy(m->message, message, MAX_MESSAGE_SIZE-1); + m->message[MAX_MESSAGE_SIZE-1] = 0; m->next = NULL; if (cs->lastmessage) { @@ -1458,7 +1459,8 @@ int BotFindMatch(char *str, bot_match_t *match, unsigned long int context) int i; bot_matchtemplate_t *ms; - strncpy(match->string, str, MAX_MESSAGE_SIZE); + strncpy(match->string, str, MAX_MESSAGE_SIZE-1); + match->string[MAX_MESSAGE_SIZE-1] = 0; //remove any trailing enters while(strlen(match->string) && match->string[strlen(match->string)-1] == '\n') @@ -2117,7 +2119,8 @@ bot_chat_t *BotLoadInitialChat(char *chatfile, char *chatname) if (pass) { chattype = (bot_chattype_t *) ptr; - strncpy(chattype->name, token.string, MAX_CHATTYPE_NAME); + strncpy(chattype->name, token.string, MAX_CHATTYPE_NAME-1); + chattype->name[MAX_CHATTYPE_NAME-1] = 0; chattype->firstchatmessage = NULL; //add the chat type to the chat chattype->next = chat->types; diff --git a/engine/botlib/be_ai_goal.c b/engine/botlib/be_ai_goal.c index 085284d29..df24c1129 100644 --- a/engine/botlib/be_ai_goal.c +++ b/engine/botlib/be_ai_goal.c @@ -283,7 +283,8 @@ itemconfig_t *LoadItemConfig(char *filename) LibVarSet( "max_iteminfo", "256" ); } - strncpy( path, filename, MAX_PATH ); + strncpy( path, filename, MAX_PATH-1 ); + path[MAX_PATH-1] = 0; PC_SetBaseFolder(BOTFILESBASEFOLDER); source = LoadSourceFile( path ); if( !source ) { @@ -316,7 +317,14 @@ itemconfig_t *LoadItemConfig(char *filename) return NULL; } //end if StripDoubleQuotes(token.string); - strncpy(ii->classname, token.string, sizeof(ii->classname)-1); + if (strlen(token.string) >= sizeof(ii->classname)) + { + SourceError(source, "more than %d chars\n", sizeof(ii->classname)-1); + FreeMemory(ic); + FreeSource(source); + return NULL; + } + strcpy(ii->classname, token.string); if (!ReadStructure(source, &iteminfo_struct, (char *) ii)) { FreeMemory(ic); @@ -688,8 +696,11 @@ void BotGoalName(int number, char *name, int size) { if (li->number == number) { - strncpy(name, itemconfig->iteminfo[li->iteminfo].name, size-1); - name[size-1] = '\0'; + size_t r = strlen(itemconfig->iteminfo[li->iteminfo].name); + if (r > size-1) + r = size-1; //truncate... + memcpy(name, itemconfig->iteminfo[li->iteminfo].name, r); + name[r] = '\0'; return; } //end for } //end for diff --git a/engine/botlib/be_ai_weap.c b/engine/botlib/be_ai_weap.c index 1fe2ddacb..227c377e9 100644 --- a/engine/botlib/be_ai_weap.c +++ b/engine/botlib/be_ai_weap.c @@ -219,7 +219,8 @@ weaponconfig_t *LoadWeaponConfig(char *filename) max_projectileinfo = 32; LibVarSet("max_projectileinfo", "32"); } //end if - strncpy(path, filename, MAX_PATH); + strncpy(path, filename, sizeof(path)-1); + path[sizeof(path)-1] = 0; PC_SetBaseFolder(BOTFILESBASEFOLDER); source = LoadSourceFile(path); if (!source) diff --git a/engine/botlib/l_log.c b/engine/botlib/l_log.c index bf5cd401c..23293600f 100644 --- a/engine/botlib/l_log.c +++ b/engine/botlib/l_log.c @@ -75,7 +75,8 @@ void Log_Open(char *filename) botimport.Print(PRT_ERROR, "can't open the log file %s\n", filename); return; } //end if - strncpy(logfile.filename, filename, MAX_LOGFILENAMESIZE); + strncpy(logfile.filename, filename, MAX_LOGFILENAMESIZE-1); + logfile.filename[MAX_LOGFILENAMESIZE-1] = 0; botimport.Print(PRT_MESSAGE, "Opened log %s\n", logfile.filename); } //end of the function Log_Create //=========================================================================== diff --git a/engine/botlib/l_precomp.c b/engine/botlib/l_precomp.c index 33080bbb0..98cd90793 100644 --- a/engine/botlib/l_precomp.c +++ b/engine/botlib/l_precomp.c @@ -466,6 +466,7 @@ int PC_ReadDefineParms(source_t *source, define_t *define, token_t **parms, int //============================================================================ int PC_StringizeTokens(token_t *tokens, token_t *token) { + int ret = qtrue; token_t *t; token->type = TT_STRING; @@ -475,10 +476,15 @@ int PC_StringizeTokens(token_t *tokens, token_t *token) strcat(token->string, "\""); for (t = tokens; t; t = t->next) { - strncat(token->string, t->string, MAX_TOKEN - strlen(token->string) - 1); + if (strlen(token->string)+strlen(t->string) >= MAX_TOKEN-1) + { + ret = qfalse; + break; + } + strcat(token->string, t->string); } //end for strncat(token->string, "\"", MAX_TOKEN - strlen(token->string) - 1); - return qtrue; + return ret; } //end of the function PC_StringizeTokens //============================================================================ // @@ -1018,7 +1024,10 @@ int PC_Directive_include(source_t *source) break; } //end if if (token.type == TT_PUNCTUATION && *token.string == '>') break; - strncat(path, token.string, MAX_PATH - 1); + if (strlen(path) + strlen(token.string) >= MAX_PATH) + SourceWarning(source, "#include truncation"); + else + strcat(path, token.string); } //end while if (*token.string != '>') { diff --git a/engine/botlib/l_struct.c b/engine/botlib/l_struct.c index fac38cdea..8a44bca7e 100644 --- a/engine/botlib/l_struct.c +++ b/engine/botlib/l_struct.c @@ -216,15 +216,21 @@ qboolean ReadChar(source_t *source, fielddef_t *fd, void *p) int ReadString(source_t *source, fielddef_t *fd, void *p) { token_t token; + size_t s; if (!PC_ExpectTokenType(source, TT_STRING, 0, &token)) return 0; //remove the double quotes StripDoubleQuotes(token.string); //copy the string - strncpy((char *) p, token.string, MAX_STRINGFIELD); - //make sure the string is closed with a zero - ((char *)p)[MAX_STRINGFIELD-1] = '\0'; - // + s = strlen(token.string); + if (s >= MAX_STRINGFIELD) + { + s = MAX_STRINGFIELD-1; + memcpy(p, token.string, s); + ((char*)p)[s] = 0; + return 0; //truncated + } + strcpy((char*)p, token.string); return 1; } //end of the function ReadString //=========================================================================== diff --git a/engine/client/cl_input.c b/engine/client/cl_input.c index 7bab09b69..ba589af1c 100644 --- a/engine/client/cl_input.c +++ b/engine/client/cl_input.c @@ -587,7 +587,7 @@ cvar_t cl_pitchspeed = CVAR("cl_pitchspeed","150"); cvar_t cl_anglespeedkey = CVAR("cl_anglespeedkey","1.5"); -#define GATHERBIT(bname,bit) if (bname.state[pnum] & 3) {bits |= (1u<xv->dimension_solid = *csqcg.dimension_default; ent->xv->dimension_hit = *csqcg.dimension_default; +#ifdef HEXEN2 ent->xv->drawflags = SCALE_ORIGIN_ORIGIN; +#endif } } @@ -7071,7 +7074,6 @@ static qboolean CSQC_ValidateMainCSProgs(void *file, size_t filesize, unsigned i static void *CSQC_FindMainProgs(size_t *sz, const char *name, unsigned int checksum, size_t checksize) { //returns a TempFile char newname[MAX_QPATH]; - extern cvar_t sv_demo_write_csqc; void *file = NULL; //the filename we'll cache to diff --git a/engine/client/pr_skelobj.c b/engine/client/pr_skelobj.c index 7a58f8db7..de0acfea9 100644 --- a/engine/client/pr_skelobj.c +++ b/engine/client/pr_skelobj.c @@ -2075,7 +2075,7 @@ void QCBUILTIN PF_skel_build_ptr(pubprogfuncs_t *prinst, struct globalvars_s *pr lastbone = firstbone; fstate.g[FS_REG].endbone = 0x7fffffff; - for (i = 0; i < 4; i++) + for (i = 0; i < FRAME_BLENDS; i++) { fstate.g[FS_REG].frame[i] = blends->animation[i]; fstate.g[FS_REG].frametime[i] = blends->animationtime[i]; diff --git a/engine/client/sys_win.c b/engine/client/sys_win.c index fc630dbf6..313b3e402 100644 --- a/engine/client/sys_win.c +++ b/engine/client/sys_win.c @@ -1884,7 +1884,7 @@ void Sys_Clipboard_PasteText(clipboardtype_t cbt, void (*callback)(void *cb, cha free(cliputf8); GlobalUnlock(clipboardhandle); CloseClipboard(); - return cliputf8; + return; } //failed at the last hurdle diff --git a/engine/common/com_mesh.c b/engine/common/com_mesh.c index 342c4981b..835939ee5 100644 --- a/engine/common/com_mesh.c +++ b/engine/common/com_mesh.c @@ -2527,6 +2527,7 @@ static void Mod_ClampModelSize(model_t *mod) #endif } +#ifdef NONSKELETALMODELS #ifndef SERVERONLY static int R_FindTriangleWithEdge (index_t *indexes, int numtris, int start, int end, int ignore) { @@ -2581,6 +2582,7 @@ static void Mod_CompileTriangleNeighbours(model_t *loadmodel, galiasinfo_t *gali } #endif } +#endif typedef struct { diff --git a/engine/common/common.c b/engine/common/common.c index 6b13b9dd9..5ad29a529 100644 --- a/engine/common/common.c +++ b/engine/common/common.c @@ -4788,14 +4788,19 @@ COM_Version_f */ static void COM_Version_f (void) { + Con_Printf("\n"); + Con_Printf("^&F0%s\n", FULLENGINENAME); + Con_Printf("%s\n", ENGINEWEBSITE); Con_Printf("%s\n", version_string()); Con_TPrintf ("Exe: %s %s\n", __DATE__, __TIME__); - #ifdef SVNREVISION if (strcmp(STRINGIFY(SVNREVISION), "-")) Con_Printf("SVN Revision: %s\n",STRINGIFY(SVNREVISION)); #endif +#ifdef CONFIG_FILE_NAME + Con_Printf("Build config: %s\n\n", STRINGIFY(CONFIG_FILE_NAME)); +#endif #ifdef _DEBUG Con_Printf("debug build\n"); @@ -4977,11 +4982,13 @@ static void COM_Version_f (void) #else #ifdef SPEEX_STATIC Con_Printf(" speex"); + Con_DPrintf("(static)"); #else Con_Printf(" speex(dynamic)"); #endif #ifdef OPUS_STATIC Con_Printf(" opus"); + Con_DPrintf("(static)"); #else Con_Printf(" opus(dynamic)"); #endif @@ -5019,18 +5026,23 @@ static void COM_Version_f (void) Con_Printf("Misc:"); #ifdef SUBSERVERS - Con_Printf(" mapcluster(enabled)"); + Con_Printf(" mapcluster"); #else Con_DPrintf(" ^h(disabled: mapcluster)^7"); #endif #ifndef SERVERONLY #ifdef AVAIL_FREETYPE - Con_Printf(" freetype2"); + #ifdef FREETYPE_STATIC + Con_Printf(" freetype2"); + Con_DPrintf("(static)"); + #else + Con_Printf(" freetype2(dynamic)"); + #endif #else Con_DPrintf(" ^h(disabled: freetype2)^7"); #endif #ifdef AVAIL_OPENAL - Con_Printf(" openal"); + Con_Printf(" openal(dynamic)"); #else Con_DPrintf(" ^h(disabled: openal)^7"); #endif diff --git a/engine/common/config_fteqw.h b/engine/common/config_fteqw.h index dd82a7fd3..b2a55e2a3 100644 --- a/engine/common/config_fteqw.h +++ b/engine/common/config_fteqw.h @@ -180,5 +180,9 @@ #endif //-DNO_VORBISFILE //disable static vorbisfile + +//enable some staticaly linked libraries +-DLINK_FREETYPE //international text requires international fonts. + //-Os //optimise for size instead of speed. less cpu cache needed means that its sometimes faster anyway. #endif diff --git a/engine/qclib/cmdlib.h b/engine/qclib/cmdlib.h index 8c49b457b..9faeb5ea1 100644 --- a/engine/qclib/cmdlib.h +++ b/engine/qclib/cmdlib.h @@ -35,12 +35,18 @@ extern char **myargv; int QCC_filelength (int handle); int QCC_tell (int handle); +#if 0//def __GNUC__ + #define WARN_UNUSED_RESULT __attribute__((warn_unused_result)) +#else + #define WARN_UNUSED_RESULT +#endif + int QC_strcasecmp (const char *s1, const char *s2); int QC_strncasecmp(const char *s1, const char *s2, int n); -void QC_strlcat(char *dest, const char *src, size_t destsize); -void QC_strlcpy(char *dest, const char *src, size_t destsize); -void QC_strnlcpy(char *dest, const char *src, size_t srclen, size_t destsize); +pbool QC_strlcat(char *dest, const char *src, size_t destsize) WARN_UNUSED_RESULT; +pbool QC_strlcpy(char *dest, const char *src, size_t destsize) WARN_UNUSED_RESULT; +pbool QC_strnlcpy(char *dest, const char *src, size_t srclen, size_t destsize) WARN_UNUSED_RESULT; char *QC_strcasestr(const char *haystack, const char *needle); #ifdef _MSC_VER diff --git a/engine/qclib/qcc_cmdlib.c b/engine/qclib/qcc_cmdlib.c index 9096244ff..c18086256 100644 --- a/engine/qclib/qcc_cmdlib.c +++ b/engine/qclib/qcc_cmdlib.c @@ -143,39 +143,36 @@ void SetEndian(void) } -void QC_strlcat(char *dest, const char *src, size_t destsize) +pbool QC_strlcat(char *dest, const char *src, size_t destsize) { size_t curlen = strlen(dest); if (!destsize) - return; //err + return false; //err dest += curlen; while(*src && ++curlen < destsize) *dest++ = *src++; -// if (*src) -// printf("QC_strlcpy: truncation\n"); *dest = 0; + return !*src; } -void QC_strlcpy(char *dest, const char *src, size_t destsize) +pbool QC_strlcpy(char *dest, const char *src, size_t destsize) { size_t curlen = 0; if (!destsize) - return; //err + return false; //err while(*src && ++curlen < destsize) *dest++ = *src++; -// if (*src) -// printf("QC_strlcpy: truncation\n"); *dest = 0; + return !*src; } -void QC_strnlcpy(char *dest, const char *src, size_t srclen, size_t destsize) +pbool QC_strnlcpy(char *dest, const char *src, size_t srclen, size_t destsize) { size_t curlen = 0; if (!destsize) - return; //err + return false; //err for(; *src && srclen > 0 && ++curlen < destsize; srclen--) *dest++ = *src++; -// if (srclen) -// printf("QC_strlcpy: truncation\n"); *dest = 0; + return !srclen; } char *QC_strcasestr(const char *haystack, const char *needle) diff --git a/engine/qclib/qcc_pr_comp.c b/engine/qclib/qcc_pr_comp.c index c8ad717e7..21df184a1 100644 --- a/engine/qclib/qcc_pr_comp.c +++ b/engine/qclib/qcc_pr_comp.c @@ -286,10 +286,11 @@ int *pr_cases; QCC_ref_t *pr_casesref; QCC_ref_t *pr_casesref2; +#define MAX_LABEL_LENGTH 256 typedef struct { int statementno; int lineno; - char name[256]; + char name[MAX_LABEL_LENGTH]; } gotooperator_t; int max_labels; @@ -793,6 +794,7 @@ static pbool OpAssignsToB(unsigned int op) return false; } #define OpAssignsToA(op) false +#ifdef _DEBUG static int OpAssignsCount(unsigned int op) { switch(op) @@ -855,7 +857,6 @@ static int OpAssignsCount(unsigned int op) return 1; } } -#ifdef _DEBUG static void OpAssignsTo_Debug(void) { int i; @@ -10173,7 +10174,8 @@ static void QCC_PR_GotoStatement (QCC_statement_t *patch2, char *labelname) pr_gotos = realloc(pr_gotos, sizeof(*pr_gotos)*max_gotos); } - strncpy(pr_gotos[num_gotos].name, labelname, sizeof(pr_gotos[num_gotos].name) -1); + if (!QC_strlcpy(pr_gotos[num_gotos].name, labelname, sizeof(pr_gotos[num_gotos].name))) + QCC_PR_ParseWarning(WARN_STRINGTOOLONG, "Label name too long"); pr_gotos[num_gotos].lineno = pr_source_line; pr_gotos[num_gotos].statementno = patch2 - statements; diff --git a/engine/qclib/qcc_pr_lex.c b/engine/qclib/qcc_pr_lex.c index b9d2aba0f..de01e78d0 100644 --- a/engine/qclib/qcc_pr_lex.c +++ b/engine/qclib/qcc_pr_lex.c @@ -128,10 +128,16 @@ void QCC_PR_AddIncludePath(const char *newinc) { if (!*qccincludedir[i]) { + pbool trunc; const char *e = newinc + strlen(newinc)-1; - QC_strlcpy(qccincludedir[i], newinc, sizeof(qccincludedir)); + trunc = !QC_strlcpy(qccincludedir[i], newinc, sizeof(qccincludedir)); if (*e != '/' && *e != '\\') - QC_strlcat(qccincludedir[i], "/", sizeof(qccincludedir)); + trunc |= !QC_strlcat(qccincludedir[i], "/", sizeof(qccincludedir)); + if (trunc) + { + QCC_PR_ParseWarning(WARN_STRINGTOOLONG, "Include path too long."); + *qccincludedir[i] = 0; + } break; } if (!strcmp(qccincludedir[i], newinc)) @@ -469,24 +475,25 @@ static void QCC_PR_GetDefinesListEnumerate(void *vctx, void *data) CompilerConstant_t *def = data; char term[8192]; size_t termsize; + pbool success = true; QC_snprintfz(term, sizeof(term), "\n%s", def->name); if (def->numparams >= 0) { int i; - QC_strlcat(term, "(", sizeof(term)); + success &= QC_strlcat(term, "(", sizeof(term)); for (i = 0; i < def->numparams; i++) { if (i) - QC_strlcat(term, ",", sizeof(term)); - QC_strlcat(term, def->params[i], sizeof(term)); + success &= QC_strlcat(term, ",", sizeof(term)); + success &= QC_strlcat(term, def->params[i], sizeof(term)); } - QC_strlcat(term, ")", sizeof(term)); + success &= QC_strlcat(term, ")", sizeof(term)); } if (def->value && *def->value) { char *o, *i; - QC_strlcat(term, "=", sizeof(term)); + success &= QC_strlcat(term, "=", sizeof(term)); //annoying logic to skip whitespace... hopefully it won't fuck stuff up too much. for (o = term+strlen(term), i = def->value; o < term + sizeof(term)-1 && *i; ) @@ -498,6 +505,8 @@ static void QCC_PR_GetDefinesListEnumerate(void *vctx, void *data) } *o = 0; } + if (!success) //this define was too long. don't show truncated stuff. + return; termsize = strlen(term); if (ctx->length + termsize+1 > ctx->buffersize) @@ -1126,9 +1135,8 @@ static pbool QCC_PR_Precompiler(void) memmove(msg, msg+1, e-(msg+1)); msg[e-(msg+1)] = 0; } - if (strlen(msg) >= sizeof(QCC_copyright)) + if (!QC_strlcpy(QCC_copyright, msg, sizeof(QCC_copyright))) QCC_PR_ParseWarning(WARN_STRINGTOOLONG, "Copyright message is too long\n"); - QC_strlcpy(QCC_copyright, msg, sizeof(QCC_copyright)-1); } else if (!QC_strcasecmp(qcc_token, "compress")) { @@ -2806,7 +2814,8 @@ static void QCC_PR_LexGrab (void) if (*pr_framemodelname) QCC_PR_MacroFrame(pr_framemodelname, pr_macrovalue, true); - QC_strlcpy(pr_framemodelname, pr_token, sizeof(pr_framemodelname)); + if (!QC_strlcpy(pr_framemodelname, pr_token, sizeof(pr_framemodelname))) + QCC_PR_ParseWarning (WARN_STRINGTOOLONG, "$modelname name too long"); i = QCC_PR_FindMacro(pr_framemodelname); if (i) @@ -3574,7 +3583,8 @@ int QCC_PR_CheckCompConst(void) || *end == '#') break; } - QC_strnlcpy(pr_token, pr_file_p, end-pr_file_p, sizeof(pr_token)); + if (!QC_strnlcpy(pr_token, pr_file_p, end-pr_file_p, sizeof(pr_token))) + return false; //name too long to be a valid macro // externs->Printf("%s\n", pr_token); c = pHash_Get(&compconstantstable, pr_token); diff --git a/engine/qclib/qccmain.c b/engine/qclib/qccmain.c index c0742d249..a1d03d5b7 100644 --- a/engine/qclib/qccmain.c +++ b/engine/qclib/qccmain.c @@ -4567,11 +4567,12 @@ static int QCC_FindQCFiles(const char *sourcedir) } -static void QCC_GenerateRelativePath(char *dest, size_t destsize, char *base, char *relative) +static pbool QCC_GenerateRelativePath(char *dest, size_t destsize, char *base, char *relative) { int p; char *s1, *s2; - QC_strlcpy (dest, base, destsize); + if (!QC_strlcpy (dest, base, destsize)) + return false; s1 = strchr(dest, '\\'); s2 = strchr(dest, '/'); if (s2 > s1) @@ -4607,22 +4608,27 @@ static void QCC_GenerateRelativePath(char *dest, size_t destsize, char *base, ch { if (p) { //we were still looking for a separator, but didn't find one, so kill the entire path. - QC_strlcpy(dest, "", destsize); + (void)QC_strlcpy(dest, "", destsize); p--; } - else - QC_strlcat(dest, "/", destsize); + else if (!QC_strlcat(dest, "/", destsize)) + return false; } - QC_strlcat(dest, s2, destsize); + if (!QC_strlcat(dest, s2, destsize)) + return false; - while (p>0 && strlen(dest)+3 < destsize) + while (p>0) { + if (strlen(dest)+3 >= destsize) + return false; memmove(dest+3, dest, strlen(dest)+1); dest[0] = '.'; dest[1] = '.'; dest[2] = '/'; p--; } + + return true; } const char *qcccol[COL_MAX]; @@ -4769,7 +4775,7 @@ pbool QCC_main (int argc, char **argv) //as part of the quake engine time(&long_time); strftime(QCC_copyright, sizeof(QCC_copyright), "Compiled [%Y/%m/%d]. ", localtime( &long_time )); - QC_strlcat(QCC_copyright, QCC_VersionString(), sizeof(QCC_copyright)); + (void)QC_strlcat(QCC_copyright, QCC_VersionString(), sizeof(QCC_copyright)); for (p = 0; p < 5; p++) strcpy(QCC_Packname[p], ""); @@ -4913,7 +4919,7 @@ memset(pr_immediate_string, 0, sizeof(pr_immediate_string)); qccmsrc = NULL; if (!numsourcefiles) - { + { //generate an internal .src file from the argument list int i; for (i = 1;ixv->dimension_solid & (int)touch->xv->dimension_hit)) //didn't change did it?... continue; - w->Event_Touch(w, touch, ent); + w->Event_Touch(w, touch, ent, NULL); if (ED_ISFREE(ent)) break; @@ -2242,9 +2242,7 @@ static void World_ClipToNetwork (world_t *w, moveclip_t *clip) { touch = &pe->entities[i]; - if (touch->solidsize == ES_SOLID_NOT) - continue; - else if (touch->solidsize == ES_SOLID_BSP) + if (touch->solidsize == ES_SOLID_BSP) { switch(touch->skinnum) { @@ -2261,6 +2259,12 @@ static void World_ClipToNetwork (world_t *w, moveclip_t *clip) VectorCopy(model->mins, bmins); VectorCopy(model->maxs, bmaxs); } +#if 1 + else + continue; //only hit brush ents. +#else + else if (touch->solidsize == ES_SOLID_NOT) + continue; else { if (clip->type & MOVE_NOMONSTERS) @@ -2269,6 +2273,7 @@ static void World_ClipToNetwork (world_t *w, moveclip_t *clip) model = NULL; COM_DecodeSize(touch->solidsize, bmins, bmaxs); } +#endif if (!(clip->hitcontentsmask & touchcontents)) continue; @@ -2325,7 +2330,10 @@ static void World_ClipToNetwork (world_t *w, moveclip_t *clip) if (clip->trace.startsolid && !trace.startsolid) trace.ent = clip->trace.ent; //something else hit earlier, that one gets the trace entity, but not the fraction. yeah, combining traces like this was always going to be weird. else - trace.ent = touch; + { + trace.ent = NULL; + clip->trace.entnum = touch->number; + } clip->trace = trace; } else if (trace.startsolid || trace.allsolid) @@ -2336,7 +2344,8 @@ static void World_ClipToNetwork (world_t *w, moveclip_t *clip) if (!clip->trace.ent || trace.fraction == clip->trace.fraction) //xonotic requires that second test (DP has no check at all, which would end up reporting mismatched fraction/ent results, so yuck). { clip->trace.contents = trace.contents; - clip->trace.ent = touch; + clip->trace.ent = NULL; + clip->trace.entnum = touch->number; } } }