Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,15 @@ jobs:
grep -q "argc as kal_env_arg_count = 3" <<<"$out" || { echo "::error::the image's arguments"; exit 1; }
grep -q "mix = 204" <<<"$out" || { echo "::error::the calling convention"; exit 1; }
grep -q "tls main=1 ctx1=10 ctx2=20" <<<"$out" || { echo "::error::thread-local storage or the callback"; exit 1; }
# A RELATIVE NAME THAT CLIMBS (0.6.2): `..' above the working
# directory folds against its name and opens through the supplied
# directory that then holds it; `./' beside it and an absolute name
# already ran.
mkdir -p rel/below
(cd rel/below && "$OKRUN" ../../"out/$a/hello.oke" one | tr -d '\r' \
| grep -q "argc as kal_env_arg_count = 2") \
|| { echo "::error::a relative image name with .. was not opened"; exit 1; }
echo " ok a relative name that climbs opens the image"
n=$("$OKRUN" "out/$a/needed.oke" | tr -d '\r')
echo "$n"
grep -q "twice(21) = 42, next_value() = 41" <<<"$n" || { echo "::error::an image another needs"; exit 1; }
Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,14 @@ states the system's base), where openkal-freebsd is hosted, and over
openkal-musl (`<arch>-freebsd-musl`), whose graph already holds openkal-freebsd
standalone. No other change.

Version 0.6.2 opens an image whose relative name climbs above the working
directory (`../image.oke`). Such a name was passed to the file system as it
stood, and an openkal name admits no `..` component, so the image was refused.
The runner now folds a relative name against the first directory's name ---
`..' and `.' lexically, a symlink left to the file system --- into the absolute
name beneath it, which is matched against the supplied directories as an
absolute one is. No other change.

## An image

```sh
Expand Down
2 changes: 1 addition & 1 deletion bind/mcpp.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
namespace = "mcpplibs"
name = "openkal-bind"
version = "0.6.1"
version = "0.6.2"
# `mcpp::xpkg_request', `mcpp::decision' (protocol 15).
mcpp = ">=2026.10.1.3"
description = "A build plugin: a library published as an ok image (.okso) and a C header is called from a program of any system, through a binding generated from the header and libokrun."
Expand Down
2 changes: 1 addition & 1 deletion ld/mcpp.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
namespace = "mcpplibs"
name = "openkal-ld"
version = "0.6.1"
version = "0.6.2"
description = "libokld: the ok format (openkal image format) --- its definition, a reader of bytes, a checker, a signer, and a loader. Freestanding: no C library, no exceptions."
license = "Apache-2.0"
authors = ["mcpplibs"]
Expand Down
2 changes: 1 addition & 1 deletion run/mcpp.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
namespace = "mcpplibs"
name = "openkal-run"
version = "0.6.1"
version = "0.6.2"
description = "libokrun: the runner's core --- an ok image's names bound to this process's one openkal implementation, in the image's calling convention, and its entry entered."
license = "Apache-2.0"
authors = ["mcpplibs"]
Expand Down
54 changes: 41 additions & 13 deletions run/src/run.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,33 +67,61 @@ void* allocate(okld_size n, void*) { return kal_alloc(n, 16); }
void deallocate(void* p, okld_size n, void*) { kal_free(p, n, 16); }

// A name as openkal names things: the supplied directory that is the longest
// prefix of it, and the rest. A relative name is beneath the first.
// prefix of it, and the rest. A relative name is folded against the first
// directory's name --- `..' and `.' lexically, a symlink not resolved --- into
// the absolute one beneath it and matched as that. It folds into `g_folded',
// which outlives the call: the rest points into it.
bool separator(char c) { return c == '/' || c == '\\'; }
char lower(char c) { return (c >= 'A' && c <= 'Z') ? static_cast<char>(c - 'A' + 'a') : c; }

char g_folded[1024];

bool locate(const char* path, kal_dir& dir, const char*& rest) {
const bool absolute = separator(path[0]) || (path[0] && path[1] == ':');
if (!absolute) {
char name[8]; kal_uintptr len = 0;
if (kal_fs_preopen(0, &dir, name, sizeof name, &len) != kal_ok) return false;
rest = path;
while (rest[0] == '.' && separator(rest[1])) rest += 2;
return true;
const char* name = path;
if (!(separator(path[0]) || (path[0] && path[1] == ':'))) {
char base[1024]; kal_uintptr blen = 0;
if (kal_fs_preopen(0, &dir, base, sizeof base, &blen) != kal_ok
|| blen == 0 || blen >= sizeof g_folded) return false;
unsigned long at = 0;
while (at < blen) { g_folded[at] = base[at]; ++at; }
if (!separator(g_folded[at - 1])) g_folded[at++] = '/';
// `..' may climb out of the first directory, to the root of what it
// then names: the whole tree, or a drive's. No higher.
unsigned long floor = at;
if (blen > 1 && separator(g_folded[0])) floor = 1;
else if (blen > 3 && g_folded[1] == ':' && separator(g_folded[2])) floor = 3;
for (const char* p = path; *p;) {
const char* s = p;
while (*p && !separator(*p)) ++p;
const unsigned long n = static_cast<unsigned long>(p - s);
while (separator(*p)) ++p;
if (n == 0 || (n == 1 && s[0] == '.')) continue;
if (n == 2 && s[0] == '.' && s[1] == '.') {
if (at <= floor) return false;
do --at; while (at > floor && !separator(g_folded[at - 1]));
continue;
}
if (at && !separator(g_folded[at - 1])) g_folded[at++] = '/';
if (at + n >= sizeof g_folded) return false;
for (unsigned long i = 0; i < n; ++i) g_folded[at++] = s[i];
}
g_folded[at] = 0;
name = g_folded;
}
unsigned long best = 0;
bool found = false;
for (kal_uintptr i = 0; i < kal_fs_preopen_count(); ++i) {
kal_dir d{}; char name[1024]; kal_uintptr len = 0;
if (kal_fs_preopen(i, &d, name, sizeof name, &len) != kal_ok || len == 0 || len >= sizeof name) continue;
kal_dir d{}; char pname[1024]; kal_uintptr len = 0;
if (kal_fs_preopen(i, &d, pname, sizeof pname, &len) != kal_ok || len == 0 || len >= sizeof pname) continue;
unsigned long k = 0;
while (k < len && path[k] && (lower(path[k]) == lower(name[k]) || (separator(path[k]) && separator(name[k])))) ++k;
while (k < len && name[k] && (lower(name[k]) == lower(pname[k]) || (separator(name[k]) && separator(pname[k])))) ++k;
if (k != len) continue;
if (!separator(name[len - 1]) && path[len] && !separator(path[len])) continue;
if (!separator(pname[len - 1]) && name[len] && !separator(name[len])) continue;
if (found && len <= best) continue;
best = len; found = true; dir = d;
}
if (!found) return false;
rest = path + best;
rest = name + best;
while (separator(*rest)) ++rest;
return true;
}
Expand Down
2 changes: 1 addition & 1 deletion tools/mcpp.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
namespace = "mcpplibs"
name = "openkal-tools"
version = "0.6.1"
version = "0.6.2"
description = "okrun, which runs an ok image on this system, and okld, the format's tool on a build machine (check, note, sign, inspect)."
license = "Apache-2.0"
authors = ["mcpplibs"]
Expand Down
Loading