diff --git a/core/HalfLife2.cpp b/core/HalfLife2.cpp index a9feccff..a2e97991 100644 --- a/core/HalfLife2.cpp +++ b/core/HalfLife2.cpp @@ -337,8 +337,13 @@ bool UTIL_FindInSendTable(SendTable *pTable, return false; } -typedescription_t *UTIL_FindInDataMap(datamap_t *pMap, const char *name) +typedescription_t *UTIL_FindInDataMap(datamap_t *pMap, const char *name, bool *isNested) { + if (isNested) + { + *isNested = false; + } + while (pMap) { for (int i=0; idataNumFields; i++) @@ -353,10 +358,21 @@ typedescription_t *UTIL_FindInDataMap(datamap_t *pMap, const char *name) } if (pMap->dataDesc[i].td) { - typedescription_t *_td; - if ((_td=UTIL_FindInDataMap(pMap->dataDesc[i].td, name)) != NULL) + if (isNested) { - return _td; + *isNested = (UTIL_FindInDataMap(pMap->dataDesc[i].td, name, NULL) != NULL); + if (*isNested) + { + return NULL; + } else { + continue; + } + } else { // Use the old behaviour, we dont want to spring this on extensions - even if they're doing bad things. + typedescription_t *_td; + if ((_td=UTIL_FindInDataMap(pMap->dataDesc[i].td, name, NULL)) != NULL) + { + return _td; + } } } } @@ -449,6 +465,11 @@ SendProp *CHalfLife2::FindInSendTable(const char *classname, const char *offset) } typedescription_t *CHalfLife2::FindInDataMap(datamap_t *pMap, const char *offset) +{ + return this->FindInDataMap(pMap, offset, NULL); +} + +typedescription_t *CHalfLife2::FindInDataMap(datamap_t *pMap, const char *offset, bool *isNested) { typedescription_t *td = NULL; DataMapTrie &val = m_Maps[pMap]; @@ -459,7 +480,7 @@ typedescription_t *CHalfLife2::FindInDataMap(datamap_t *pMap, const char *offset } if (!sm_trie_retrieve(val.trie, offset, (void **)&td)) { - if ((td = UTIL_FindInDataMap(pMap, offset)) != NULL) + if ((td = UTIL_FindInDataMap(pMap, offset, isNested)) != NULL) { sm_trie_insert(val.trie, offset, td); } diff --git a/core/HalfLife2.h b/core/HalfLife2.h index 047affd8..33792dc0 100644 --- a/core/HalfLife2.h +++ b/core/HalfLife2.h @@ -123,6 +123,7 @@ public: //IGameHelpers datamap_t *GetDataMap(CBaseEntity *pEntity); ServerClass *FindServerClass(const char *classname); typedescription_t *FindInDataMap(datamap_t *pMap, const char *offset); + typedescription_t *FindInDataMap(datamap_t *pMap, const char *offset, bool *isNested); void SetEdictStateChanged(edict_t *pEdict, unsigned short offset); bool TextMsg(int client, int dest, const char *msg); bool HintTextMsg(int client, const char *msg); diff --git a/core/smn_entities.cpp b/core/smn_entities.cpp index 02a4c219..8870ac58 100644 --- a/core/smn_entities.cpp +++ b/core/smn_entities.cpp @@ -815,9 +815,13 @@ static cell_t FindDataMapOffs(IPluginContext *pContext, const cell_t *params) } pContext->LocalToString(params[2], &offset); - if ((td=g_HL2.FindInDataMap(pMap, offset)) == NULL) + bool isNested = false; + if ((td=g_HL2.FindInDataMap(pMap, offset, &isNested)) == NULL) { - return -1; + if (isNested) + return pContext->ThrowNativeError("Property \"%s\" is not safe to access for entity %d", offset, params[1]); + else + return -1; } if (params[0] == 4) @@ -962,13 +966,22 @@ static cell_t SetEntDataString(IPluginContext *pContext, const cell_t *params) { \ return pContext->ThrowNativeError("Could not retrieve datamap"); \ } \ - if ((td = g_HL2.FindInDataMap(pMap, prop)) == NULL) \ + bool isNested = false; \ + if ((td = g_HL2.FindInDataMap(pMap, prop, &isNested)) == NULL) \ { \ const char *class_name = g_HL2.GetEntityClassname(pEntity); \ - return pContext->ThrowNativeError("Property \"%s\" not found (entity %d/%s)", \ - prop, \ - params[1], \ - ((class_name) ? class_name : "")); \ + if (isNested) \ + { \ + return pContext->ThrowNativeError("Property \"%s\" not safe to access (entity %d/%s)", \ + prop, \ + params[1], \ + ((class_name) ? class_name : "")); \ + } else { \ + return pContext->ThrowNativeError("Property \"%s\" not found (entity %d/%s)", \ + prop, \ + params[1], \ + ((class_name) ? class_name : "")); \ + } \ } #define CHECK_SET_PROP_DATA_OFFSET() \ @@ -1889,9 +1902,13 @@ static cell_t SetEntPropString(IPluginContext *pContext, const cell_t *params) return pContext->ThrowNativeError("Unable to retrieve GetDataDescMap offset"); } pContext->LocalToString(params[3], &prop); - if ((td=g_HL2.FindInDataMap(pMap, prop)) == NULL) + bool isNested = false; + if ((td=g_HL2.FindInDataMap(pMap, prop, &isNested)) == NULL) { - return pContext->ThrowNativeError("Property \"%s\" not found for entity %d", prop, params[1]); + if (isNested) + return pContext->ThrowNativeError("Property \"%s\" is not safe to access for entity %d", prop, params[1]); + else + return pContext->ThrowNativeError("Property \"%s\" not found for entity %d", prop, params[1]); } if (td->fieldType != FIELD_CHARACTER) {