From 773b5f759c63bb845b76300e10bef28bb0a11eba Mon Sep 17 00:00:00 2001 From: Leonid Pospelov Date: Mon, 15 Apr 2024 00:35:26 +0500 Subject: [PATCH 1/3] fix: improve setDisplayName security & more --- skymp5-client/src/services/services/remoteServer.ts | 7 ++----- skymp5-client/src/services/services/spSnippetService.ts | 7 ++----- skymp5-server/cpp/server_guest_lib/MpObjectReference.cpp | 2 +- skymp5-server/cpp/server_guest_lib/MpObjectReference.h | 2 +- .../script_classes/PapyrusObjectReference.cpp | 8 +++++++- .../script_classes/PapyrusObjectReference.h | 2 ++ 6 files changed, 15 insertions(+), 13 deletions(-) diff --git a/skymp5-client/src/services/services/remoteServer.ts b/skymp5-client/src/services/services/remoteServer.ts index 6db9ebb7d9..755dfd7ecf 100644 --- a/skymp5-client/src/services/services/remoteServer.ts +++ b/skymp5-client/src/services/services/remoteServer.ts @@ -310,11 +310,8 @@ export class RemoteServer extends ClientListener { const replaceValue = refr.getBaseObject()?.getName(); - if (replaceValue !== undefined && replaceValue !== "%original_name%") { - // SP doesn't support String.replaceAll because Chakracore doesn't - while (displayName.includes("%original_name%")) { - displayName = displayName.replace("%original_name%", replaceValue); - } + if (replaceValue !== undefined) { + displayName = displayName.replace(/%original_name%/g, replaceValue); } else { logError(this, "Couldn't get a replaceValue for SetDisplayName, refr.getFormID() was", refr.getFormID().toString(16)); diff --git a/skymp5-client/src/services/services/spSnippetService.ts b/skymp5-client/src/services/services/spSnippetService.ts index 2638f0c6a9..833ac0950d 100644 --- a/skymp5-client/src/services/services/spSnippetService.ts +++ b/skymp5-client/src/services/services/spSnippetService.ts @@ -62,11 +62,8 @@ export class SpSnippetService extends ClientListener { const replaceValue = self?.getBaseObject()?.getName(); - if (replaceValue !== undefined && replaceValue !== "%original_name%") { - // SP doesn't support String.replaceAll because Chakracore doesn't - while (newName.includes("%original_name%")) { - newName = newName.replace("%original_name%", replaceValue); - } + if (replaceValue !== undefined) { + newName = newName.replace(/%original_name%/g, replaceValue); snippet.arguments[0] = newName; } else { diff --git a/skymp5-server/cpp/server_guest_lib/MpObjectReference.cpp b/skymp5-server/cpp/server_guest_lib/MpObjectReference.cpp index dd02a45efb..f2a10bbd0f 100644 --- a/skymp5-server/cpp/server_guest_lib/MpObjectReference.cpp +++ b/skymp5-server/cpp/server_guest_lib/MpObjectReference.cpp @@ -998,7 +998,7 @@ void MpObjectReference::SetNodeScale(const std::string& node, float scale, }); } -void MpObjectReference::SetDisplayName(const std::string& newName) +void MpObjectReference::SetDisplayName(const std::optional& newName) { EditChangeForm( [&](MpChangeForm& changeForm) { changeForm.displayName = newName; }); diff --git a/skymp5-server/cpp/server_guest_lib/MpObjectReference.h b/skymp5-server/cpp/server_guest_lib/MpObjectReference.h index 42f5d33c53..874fb5b89e 100644 --- a/skymp5-server/cpp/server_guest_lib/MpObjectReference.h +++ b/skymp5-server/cpp/server_guest_lib/MpObjectReference.h @@ -150,7 +150,7 @@ class MpObjectReference const espm::LookupResult& textureSet, bool firstPerson); void SetNodeScale(const std::string& node, float scale, bool firstPerson); - void SetDisplayName(const std::string& newName); + void SetDisplayName(const std::optional& newName); const std::set& GetListeners() const; const std::set& GetEmitters() const; diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusObjectReference.cpp b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusObjectReference.cpp index 534373f1ac..4f8a7f783c 100644 --- a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusObjectReference.cpp +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusObjectReference.cpp @@ -856,7 +856,13 @@ VarValue PapyrusObjectReference::SetDisplayName( throw std::runtime_error("SetDisplayName requires at least 2 arguments"); } const char* displayName = static_cast(arguments[0]); - selfRefr->SetDisplayName(displayName); + + if (!strcmp(displayName, kOriginalNameExpression)) { + selfRefr->SetDisplayName(std::nullopt); + } + else { + selfRefr->SetDisplayName(displayName); + } bool force = static_cast(arguments[1]); std::ignore = force; diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusObjectReference.h b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusObjectReference.h index 522e83fd38..eb7d2e7301 100644 --- a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusObjectReference.h +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusObjectReference.h @@ -69,6 +69,8 @@ class PapyrusObjectReference final VarValue IsContainerEmpty(VarValue self, const std::vector& arguments); + static constexpr auto kOriginalNameExpression = R"(%original_name%)"; + // %original_name% will be replaced with the original localized name // client-side VarValue SetDisplayName(VarValue self, From ae1ef1c5e2ccc8ef3f9735f1c32cbabd830a8686 Mon Sep 17 00:00:00 2001 From: Leonid Pospelov Date: Mon, 15 Apr 2024 00:36:29 +0500 Subject: [PATCH 2/3] formt --- skymp5-server/cpp/server_guest_lib/MpObjectReference.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/skymp5-server/cpp/server_guest_lib/MpObjectReference.cpp b/skymp5-server/cpp/server_guest_lib/MpObjectReference.cpp index f2a10bbd0f..9855e00d03 100644 --- a/skymp5-server/cpp/server_guest_lib/MpObjectReference.cpp +++ b/skymp5-server/cpp/server_guest_lib/MpObjectReference.cpp @@ -998,7 +998,8 @@ void MpObjectReference::SetNodeScale(const std::string& node, float scale, }); } -void MpObjectReference::SetDisplayName(const std::optional& newName) +void MpObjectReference::SetDisplayName( + const std::optional& newName) { EditChangeForm( [&](MpChangeForm& changeForm) { changeForm.displayName = newName; }); From bd4f6bcabe0e65952e6a40cd4da99577c6a7ecc9 Mon Sep 17 00:00:00 2001 From: Leonid Pospelov Date: Mon, 15 Apr 2024 00:41:12 +0500 Subject: [PATCH 3/3] reformat --- .../server_guest_lib/script_classes/PapyrusObjectReference.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusObjectReference.cpp b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusObjectReference.cpp index 4f8a7f783c..115dcbe045 100644 --- a/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusObjectReference.cpp +++ b/skymp5-server/cpp/server_guest_lib/script_classes/PapyrusObjectReference.cpp @@ -859,8 +859,7 @@ VarValue PapyrusObjectReference::SetDisplayName( if (!strcmp(displayName, kOriginalNameExpression)) { selfRefr->SetDisplayName(std::nullopt); - } - else { + } else { selfRefr->SetDisplayName(displayName); }