Fixed duplication
All checks were successful
CI / React UI Build (push) Successful in 39s
CI / Native Windows Build And Tests (push) Successful in 2m23s
CI / Windows Release Package (push) Successful in 3m6s

This commit is contained in:
2026-06-01 06:52:56 -04:00
parent 171b790fa3
commit b7ce079a26
5 changed files with 128 additions and 124 deletions

View File

@@ -1,6 +1,8 @@
#include "stdafx.h"
#include "ShaderManifestParser.h"
#include "ShaderUiPath.h"
#include <algorithm>
#include <cmath>
#include <cctype>
@@ -47,46 +49,6 @@ bool ParseTemporalHistorySource(const std::string& sourceName, TemporalHistorySo
return false;
}
bool IsSafeUiEntryPath(const std::string& entryPath)
{
if (Trim(entryPath).empty())
return false;
if (entryPath.find('\\') != std::string::npos || entryPath.find(':') != std::string::npos ||
entryPath.find('?') != std::string::npos || entryPath.find('#') != std::string::npos)
return false;
const std::filesystem::path path(entryPath);
if (path.empty() || path.is_absolute())
return false;
bool firstPart = true;
bool startsInUiDirectory = false;
for (const std::filesystem::path& part : path)
{
if (part.empty() || part == "." || part == "..")
return false;
if (firstPart)
{
startsInUiDirectory = part == "ui";
firstPart = false;
}
}
if (!startsInUiDirectory)
return false;
const std::filesystem::path normalized = path.lexically_normal();
if (normalized.empty() || normalized.is_absolute())
return false;
for (const std::filesystem::path& part : normalized)
{
if (part.empty() || part == "." || part == "..")
return false;
}
const std::string extension = normalized.extension().string();
return extension == ".js" || extension == ".mjs";
}
bool IsValidCustomElementTag(const std::string& tag)
{
if (tag.empty() || tag.find('-') == std::string::npos || tag.front() == '-' || tag.back() == '-')
@@ -450,7 +412,9 @@ bool ParseUiDefinition(const JsonValue& manifestJson, ShaderPackage& shaderPacka
error = "Shader UI type must be 'webComponent' in: " + ManifestPathMessage(manifestPath);
return false;
}
if (!IsSafeUiEntryPath(ui.entryPath))
std::filesystem::path normalizedEntryPath;
if (!ShaderUiPath::NormalizeAssetPath(ui.entryPath, normalizedEntryPath) ||
!ShaderUiPath::IsModulePath(normalizedEntryPath))
{
error = "Shader UI entry must be a safe relative .js or .mjs path under ui/ in: " + ManifestPathMessage(manifestPath);
return false;
@@ -461,14 +425,15 @@ bool ParseUiDefinition(const JsonValue& manifestJson, ShaderPackage& shaderPacka
return false;
}
const std::filesystem::path entryPath = shaderPackage.directoryPath / std::filesystem::path(ui.entryPath);
if (!std::filesystem::exists(entryPath))
std::filesystem::path entryPath;
if (!ShaderUiPath::ResolveAssetPath(shaderPackage.directoryPath, ui.entryPath, entryPath))
{
error = "Shader UI entry not found for package " + shaderPackage.id + ": " + entryPath.string();
error = "Shader UI entry not found for package " + shaderPackage.id + ": " +
(shaderPackage.directoryPath / normalizedEntryPath).string();
return false;
}
ui.entryPath = std::filesystem::path(ui.entryPath).lexically_normal().generic_string();
ui.entryPath = normalizedEntryPath.generic_string();
ui.enabled = true;
shaderPackage.ui = ui;
return true;