From: bones_was_here Date: Sun, 4 Aug 2024 10:49:40 +0000 (+1000) Subject: edict: fix escape parsing and make exceptions configurable X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=9f8bfeb825c41dac016d0cb0dabd236be812cdae;p=xonotic%2Fdarkplaces.git edict: fix escape parsing and make exceptions configurable In 312123ecffc7e3dd892c7df754c911b47b9cdfaa a bug was introduced where newlines were no longer supported in string fields. This patch supports them again, which requires exceptions be reintroduced to fully support some buggy maps, but this time there's a cvar for documentation and adjustment. The other notes and fixes in https://github.com/DarkPlacesEngine/darkplaces/pull/185 still apply. Signed-off-by: bones_was_here --- diff --git a/prvm_edict.c b/prvm_edict.c index d4a2120f..cc318e99 100644 --- a/prvm_edict.c +++ b/prvm_edict.c @@ -53,6 +53,7 @@ cvar_t prvm_garbagecollection_notify = {CF_CLIENT | CF_SERVER, "prvm_garbagecoll cvar_t prvm_garbagecollection_scan_limit = {CF_CLIENT | CF_SERVER, "prvm_garbagecollection_scan_limit", "50000", "scan this many fields or resources per second to free up unreferenced resources"}; cvar_t prvm_garbagecollection_strings = {CF_CLIENT | CF_SERVER, "prvm_garbagecollection_strings", "1", "automatically call strunzone() on strings that are not referenced"}; cvar_t prvm_stringdebug = {CF_CLIENT | CF_SERVER, "prvm_stringdebug", "0", "Print debug and warning messages related to strings"}; +cvar_t sv_entfields_noescapes = {CF_SERVER, "sv_entfields_noescapes", "wad", "Space-separated list of fields in which backslashes won't be parsed as escapes when loading entities from .bsp or .ent files. This is a workaround for buggy maps with unescaped backslashes used as path separators (only forward slashes are allowed in Quake VFS paths)."}; static double prvm_reuseedicts_always_allow = 0; qbool prvm_runawaycheck = true; @@ -1280,12 +1281,11 @@ const char *PRVM_ED_ParseEdict (prvm_prog_t *prog, const char *data, prvm_edict_ { mdef_t *key; qbool anglehack; - qbool init; + qbool init = false; + qbool parsebackslash = true; char keyname[256]; size_t n; - init = false; - // go through all the dictionary pairs while (1) { @@ -1311,20 +1311,35 @@ const char *PRVM_ED_ParseEdict (prvm_prog_t *prog, const char *data, prvm_edict_ if (!strcmp(com_token, "light")) dp_strlcpy (com_token, "light_lev", sizeof(com_token)); // hack for single light def - dp_strlcpy (keyname, com_token, sizeof(keyname)); + n = dp_strlcpy (keyname, com_token, sizeof(keyname)); // another hack to fix keynames with trailing spaces - n = strlen(keyname); while (n && keyname[n-1] == ' ') { keyname[n-1] = 0; n--; } + // Check if escape parsing is disabled for this key (see cvar description). + // Escapes are always used in savegames and DP_QC_ENTITYSTRING for compatibility. + if (!saveload) + { + const char *cvarpos = sv_entfields_noescapes.string; + + while (COM_ParseToken_Console(&cvarpos)) + { + if (strcmp(com_token, keyname) == 0) + { + parsebackslash = false; + break; + } + } + } + // parse value // If loading a save, unescape characters (they're escaped when saving). // Otherwise, load them as they are (BSP compilers don't support escaping). - if (!COM_ParseToken_Simple(&data, false, saveload, true)) + if (!COM_ParseToken_Simple(&data, false, parsebackslash, true)) prog->error_cmd("PRVM_ED_ParseEdict: EOF without closing brace"); if (developer_entityparsing.integer) Con_Printf(" \"%s\"\n", com_token); @@ -1361,7 +1376,8 @@ const char *PRVM_ED_ParseEdict (prvm_prog_t *prog, const char *data, prvm_edict_ prog->error_cmd("PRVM_ED_ParseEdict: parse error"); } - if (!init) { + if (!init) + { ent->free = true; ent->freetime = host.realtime; } @@ -3191,6 +3207,7 @@ void PRVM_Init (void) Cvar_RegisterVariable (&prvm_garbagecollection_scan_limit); Cvar_RegisterVariable (&prvm_garbagecollection_strings); Cvar_RegisterVariable (&prvm_stringdebug); + Cvar_RegisterVariable (&sv_entfields_noescapes); // COMMANDLINEOPTION: PRVM: -norunaway disables the runaway loop check (it might be impossible to exit DarkPlaces if used!) prvm_runawaycheck = !Sys_CheckParm("-norunaway");