[keel] Fix a use after free, cleanup
Some checks are pending
Build / build (push) Waiting to run

This commit is contained in:
Gary Talent 2024-12-20 00:28:00 -06:00
parent aaeec20ac9
commit fd64bfae13
2 changed files with 41 additions and 36 deletions

View File

@ -33,7 +33,7 @@ ox::Result<std::size_t> getPreloadAddr(keel::Context &ctx, ox::FileAddress const
ox::Result<std::size_t> getPreloadAddr(keel::Context &ctx, ox::StringViewCR path) noexcept; ox::Result<std::size_t> getPreloadAddr(keel::Context &ctx, ox::StringViewCR path) noexcept;
void createUuidMapping(Context &ctx, ox::StringView filePath, ox::UUID const&uuid) noexcept; void createUuidMapping(Context &ctx, ox::StringViewCR filePath, ox::UUID const&uuid) noexcept;
ox::Error buildUuidMap(Context &ctx) noexcept; ox::Error buildUuidMap(Context &ctx) noexcept;
@ -41,17 +41,17 @@ ox::Result<ox::UUID> pathToUuid(Context &ctx, ox::StringViewCR path) noexcept;
ox::Result<ox::UUID> getUuid(Context &ctx, ox::FileAddress const&fileAddr) noexcept; ox::Result<ox::UUID> getUuid(Context &ctx, ox::FileAddress const&fileAddr) noexcept;
ox::Result<ox::UUID> getUuid(Context &ctx, ox::StringView path) noexcept; ox::Result<ox::UUID> getUuid(Context &ctx, ox::StringViewCR path) noexcept;
ox::Result<ox::CStringView> getPath(Context &ctx, ox::FileAddress const&fileAddr) noexcept; ox::Result<ox::CStringView> getPath(Context &ctx, ox::FileAddress const&fileAddr) noexcept;
ox::Result<ox::CStringView> getPath(Context &ctx, ox::CStringView fileId) noexcept; ox::Result<ox::CStringView> getPath(Context &ctx, ox::CStringViewCR fileId) noexcept;
constexpr ox::Result<ox::UUID> uuidUrlToUuid(ox::StringView uuidUrl) noexcept { constexpr ox::Result<ox::UUID> uuidUrlToUuid(ox::StringViewCR uuidUrl) noexcept {
return ox::UUID::fromString(substr(uuidUrl, 7)); return ox::UUID::fromString(substr(uuidUrl, 7));
} }
ox::Result<ox::CStringView> uuidUrlToPath(Context &ctx, ox::StringView uuid) noexcept; ox::Result<ox::CStringView> uuidUrlToPath(Context &ctx, ox::StringViewCR uuid) noexcept;
ox::Result<ox::CStringView> uuidToPath(Context &ctx, ox::StringViewCR uuid) noexcept; ox::Result<ox::CStringView> uuidToPath(Context &ctx, ox::StringViewCR uuid) noexcept;
@ -62,7 +62,7 @@ ox::Result<ox::CStringView> uuidToPath(Context &ctx, ox::UUID const&uuid) noexce
namespace detail { namespace detail {
template<typename T> template<typename T>
constexpr auto makeLoader(Context &ctx) { constexpr auto makeLoader(Context &ctx) {
return [&ctx](ox::StringView assetId) -> ox::Result<T> { return [&ctx](ox::StringViewCR assetId) -> ox::Result<T> {
OX_REQUIRE(p, ctx.uuidToPath.at(assetId)); OX_REQUIRE(p, ctx.uuidToPath.at(assetId));
OX_REQUIRE(buff, ctx.rom->read(*p)); OX_REQUIRE(buff, ctx.rom->read(*p));
auto [obj, err] = readAsset<T>(buff); auto [obj, err] = readAsset<T>(buff);
@ -80,27 +80,34 @@ constexpr auto makeLoader(Context &ctx) {
template<typename T> template<typename T>
ox::Result<keel::AssetRef<T>> readObjFile( ox::Result<keel::AssetRef<T>> readObjFile(
keel::Context &ctx, keel::Context &ctx,
ox::StringView assetId, ox::StringViewCR assetId,
bool forceLoad) noexcept { bool const forceLoad) noexcept {
static constexpr auto load = [](
keel::Context &ctx,
ox::StringViewCR assetId,
bool forceLoad) -> ox::Result<keel::AssetRef<T>> {
if (forceLoad) {
ctx.assetManager.initTypeManager<T>(detail::makeLoader<T>, ctx);
return ctx.assetManager.loadAsset<T>(assetId);
} else {
auto [cached, err] = ctx.assetManager.getAsset<T>(assetId);
if (err) {
ctx.assetManager.initTypeManager<T>(detail::makeLoader<T>, ctx);
OX_RETURN_ERROR(ctx.assetManager.loadAsset<T>(assetId).moveTo(cached));
}
return cached;
}
};
if (beginsWith(assetId, "uuid://")) { if (beginsWith(assetId, "uuid://")) {
assetId = substr(assetId, 7); return load(ctx, substr(assetId, 7), forceLoad);
} else { } else {
auto const [uuid, uuidErr] = getUuid(ctx, assetId); auto const [uuid, uuidErr] = getUuid(ctx, assetId);
if (!uuidErr) { if (!uuidErr) {
assetId = uuid.toString(); return load(ctx, uuid.toString(), forceLoad);
} else {
return load(ctx, assetId, forceLoad);
} }
} }
if (forceLoad) {
ctx.assetManager.initTypeManager<T>(detail::makeLoader<T>, ctx);
return ctx.assetManager.loadAsset<T>(assetId);
} else {
auto [cached, err] = ctx.assetManager.getAsset<T>(assetId);
if (err) {
ctx.assetManager.initTypeManager<T>(detail::makeLoader<T>, ctx);
OX_RETURN_ERROR(ctx.assetManager.loadAsset<T>(assetId).moveTo(cached));
}
return cached;
}
} }
#else #else
@ -119,7 +126,7 @@ ox::Result<keel::AssetRef<T>> readObjNoCache(
#endif #endif
ox::Error reloadAsset(keel::Context &ctx, ox::StringView assetId) noexcept; ox::Error reloadAsset(keel::Context &ctx, ox::StringViewCR assetId) noexcept;
template<typename T> template<typename T>
ox::Result<keel::AssetRef<T>> readObj( ox::Result<keel::AssetRef<T>> readObj(
@ -163,7 +170,7 @@ ox::Error writeObj(
ox::Error setRomFs(Context &ctx, ox::UPtr<ox::FileSystem> &&fs) noexcept; ox::Error setRomFs(Context &ctx, ox::UPtr<ox::FileSystem> &&fs) noexcept;
ox::Result<ox::UniquePtr<ox::FileSystem>> loadRomFs(ox::StringViewCR path) noexcept; ox::Result<ox::UPtr<ox::FileSystem>> loadRomFs(ox::StringViewCR path) noexcept;
ox::Result<char*> loadRom(ox::StringViewCR path = "") noexcept; ox::Result<char*> loadRom(ox::StringViewCR path = "") noexcept;

View File

@ -42,7 +42,7 @@ static void clearUuidMap(Context &ctx) noexcept {
ctx.pathToUuid.clear(); ctx.pathToUuid.clear();
} }
void createUuidMapping(Context &ctx, ox::StringView filePath, ox::UUID const&uuid) noexcept { void createUuidMapping(Context &ctx, ox::StringViewCR filePath, ox::UUID const&uuid) noexcept {
ctx.pathToUuid[filePath] = uuid; ctx.pathToUuid[filePath] = uuid;
ctx.uuidToPath[uuid.toString()] = filePath; ctx.uuidToPath[uuid.toString()] = filePath;
} }
@ -88,7 +88,7 @@ ox::Result<ox::UUID> getUuid(Context &ctx, ox::FileAddress const&fileAddr) noexc
return getUuid(ctx, path); return getUuid(ctx, path);
} }
ox::Result<ox::UUID> getUuid(Context &ctx, ox::StringView path) noexcept { ox::Result<ox::UUID> getUuid(Context &ctx, ox::StringViewCR path) noexcept {
if (beginsWith(path, "uuid://")) { if (beginsWith(path, "uuid://")) {
auto const uuid = substr(path, 7); auto const uuid = substr(path, 7);
return ox::UUID::fromString(uuid); return ox::UUID::fromString(uuid);
@ -112,7 +112,7 @@ ox::Result<ox::CStringView> getPath(Context &ctx, ox::FileAddress const&fileAddr
} }
} }
ox::Result<ox::CStringView> getPath(Context &ctx, ox::CStringView fileId) noexcept { ox::Result<ox::CStringView> getPath(Context &ctx, ox::CStringViewCR fileId) noexcept {
if (beginsWith(fileId, "uuid://")) { if (beginsWith(fileId, "uuid://")) {
auto const uuid = substr(fileId, 7); auto const uuid = substr(fileId, 7);
#ifndef OX_BARE_METAL #ifndef OX_BARE_METAL
@ -126,10 +126,9 @@ ox::Result<ox::CStringView> getPath(Context &ctx, ox::CStringView fileId) noexce
} }
} }
ox::Result<ox::CStringView> uuidUrlToPath(Context &ctx, ox::StringView uuid) noexcept { ox::Result<ox::CStringView> uuidUrlToPath(Context &ctx, ox::StringViewCR uuid) noexcept {
uuid = substr(uuid, 7);
#ifndef OX_BARE_METAL #ifndef OX_BARE_METAL
OX_REQUIRE_M(out, ctx.uuidToPath.at(uuid)); OX_REQUIRE_M(out, ctx.uuidToPath.at(substr(uuid, 7)));
return ox::CStringView(*out); return ox::CStringView(*out);
#else #else
return ox::Error(1, "UUID to path conversion not supported on this platform"); return ox::Error(1, "UUID to path conversion not supported on this platform");
@ -154,19 +153,18 @@ ox::Result<ox::CStringView> uuidToPath(Context &ctx, ox::UUID const&uuid) noexce
#endif #endif
} }
ox::Error reloadAsset(keel::Context &ctx, ox::StringView assetId) noexcept { ox::Error reloadAsset(keel::Context &ctx, ox::StringViewCR assetId) noexcept {
ox::UUIDStr uuidStr; ox::UUIDStr uuidStr;
if (beginsWith(assetId, "uuid://")) { if (beginsWith(assetId, "uuid://")) {
assetId = substr(assetId, 7); return ctx.assetManager.reloadAsset(substr(assetId, 7));
OX_REQUIRE(p, keel::uuidToPath(ctx, assetId));
} else { } else {
auto const [uuid, uuidErr] = getUuid(ctx, assetId); auto const [uuid, uuidErr] = getUuid(ctx, assetId);
if (!uuidErr) { if (!uuidErr) {
uuidStr = uuid.toString(); return ctx.assetManager.reloadAsset(uuidStr);
assetId = uuidStr; } else {
return ctx.assetManager.reloadAsset(assetId);
} }
} }
return ctx.assetManager.reloadAsset(assetId);
} }
} }
@ -238,7 +236,7 @@ ox::Error setRomFs(Context &ctx, ox::UPtr<ox::FileSystem> &&fs) noexcept {
return buildUuidMap(ctx); return buildUuidMap(ctx);
} }
ox::Result<ox::UniquePtr<ox::FileSystem>> loadRomFs(ox::StringViewCR path) noexcept { ox::Result<ox::UPtr<ox::FileSystem>> loadRomFs(ox::StringViewCR path) noexcept {
auto const lastDot = ox::lastIndexOf(path, '.'); auto const lastDot = ox::lastIndexOf(path, '.');
if (!lastDot.error && substr(path, lastDot.value) == ".oxfs") { if (!lastDot.error && substr(path, lastDot.value) == ".oxfs") {
OX_REQUIRE(rom, loadRom(path)); OX_REQUIRE(rom, loadRom(path));