From ef1baabc2c429c715405a39aa8b7fa85060804c0 Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Fri, 29 Nov 2024 16:41:25 +0100 Subject: [PATCH 1/3] ci: drop OpenWrt tests for now The OpenWrt CI runs are broken and need to be redone. In order to unblock the PR pipeline, drop these tests for now to reintroduce fixed variants at a later point in time. Signed-off-by: Jo-Philipp Wich --- .github/workflows/openwrt-ci-master.yml | 53 ------------------- .github/workflows/openwrt-ci-pull-request.yml | 53 ------------------- 2 files changed, 106 deletions(-) diff --git a/.github/workflows/openwrt-ci-master.yml b/.github/workflows/openwrt-ci-master.yml index fda3f807..f95c924e 100644 --- a/.github/workflows/openwrt-ci-master.yml +++ b/.github/workflows/openwrt-ci-master.yml @@ -32,56 +32,3 @@ jobs: path: | build/scan tests/cram/**/*.t.err - - sdk_build: - name: Build with OpenWrt ${{ matrix.arch }} SDK - runs-on: ubuntu-latest - - strategy: - fail-fast: false - matrix: - include: - - arch: mips_24kc - target: ath79-generic - - - arch: arm_cortex-a9_neon - target: imx-cortexa9 - - - arch: mipsel_24kc - target: malta-le - - - arch: aarch64_cortex-a53 - target: mediatek-mt7622 - - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - - name: Determine branch name - run: | - BRANCH="${GITHUB_BASE_REF#refs/heads/}" - echo "Building for $BRANCH" - echo "BRANCH=$BRANCH" >> $GITHUB_ENV - - - name: Build with OpenWrt ${{ matrix.arch }} SDK - uses: openwrt/gh-action-sdk@v5 - env: - ARCH: ${{ matrix.arch }} - FEEDNAME: ucode_ci - PACKAGES: ucode - - - name: Move created packages to project dir - run: cp bin/packages/${{ matrix.arch }}/ucode_ci/*.ipk . || true - - - name: Store packages - uses: actions/upload-artifact@v3 - with: - name: ${{ matrix.arch }}-packages - path: "*.ipk" - - - name: Store logs - uses: actions/upload-artifact@v3 - with: - name: ${{ matrix.arch }}-logs - path: logs/ diff --git a/.github/workflows/openwrt-ci-pull-request.yml b/.github/workflows/openwrt-ci-pull-request.yml index e8c29c13..8d6ad344 100644 --- a/.github/workflows/openwrt-ci-pull-request.yml +++ b/.github/workflows/openwrt-ci-pull-request.yml @@ -34,56 +34,3 @@ jobs: path: | build/scan tests/cram/**/*.t.err - - sdk_build: - name: Build with OpenWrt ${{ matrix.arch }} SDK - runs-on: ubuntu-latest - - strategy: - fail-fast: false - matrix: - include: - - arch: mips_24kc - target: ath79-generic - - - arch: arm_cortex-a9_neon - target: imx-cortexa9 - - - arch: mipsel_24kc - target: malta-le - - - arch: aarch64_cortex-a53 - target: mediatek-mt7622 - - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - - name: Determine branch name - run: | - BRANCH="${GITHUB_BASE_REF#refs/heads/}" - echo "Building for $BRANCH" - echo "BRANCH=$BRANCH" >> $GITHUB_ENV - - - name: Build with OpenWrt ${{ matrix.arch }} SDK - uses: openwrt/gh-action-sdk@v5 - env: - ARCH: ${{ matrix.arch }} - FEEDNAME: ucode_ci - PACKAGES: ucode - - - name: Move created packages to project dir - run: cp bin/packages/${{ matrix.arch }}/ucode_ci/*.ipk . || true - - - name: Store packages - uses: actions/upload-artifact@v3 - with: - name: ${{ matrix.arch }}-packages - path: "*.ipk" - - - name: Store logs - uses: actions/upload-artifact@v3 - with: - name: ${{ matrix.arch }}-logs - path: logs/ From a6e06417785288f66c990e828cccbf9fb9836ba7 Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Fri, 29 Nov 2024 14:00:09 +0100 Subject: [PATCH 2/3] vm: resolve upvalues before pushing them onto the stack Commit e5fe6b1 ("treewide: refactor vector usage code") accidentially dropped the upvalue resolving logic from uc_vm_stack_push(), leading to unresolved upvalues leaking into the script execution context. Fixes: e5fe6b1 ("treewide: refactor vector usage code") Signed-off-by: Jo-Philipp Wich --- .../99_bugs/50_missing_upvalue_resolving | 27 +++++++++++++++++++ vm.c | 2 +- 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 tests/custom/99_bugs/50_missing_upvalue_resolving diff --git a/tests/custom/99_bugs/50_missing_upvalue_resolving b/tests/custom/99_bugs/50_missing_upvalue_resolving new file mode 100644 index 00000000..5e96634b --- /dev/null +++ b/tests/custom/99_bugs/50_missing_upvalue_resolving @@ -0,0 +1,27 @@ +Commit e5fe6b1 ("treewide: refactor vector usage code") accidentially dropped +the upvalue resolving logic from uc_vm_stack_push(), leading to unresolved +upvalues leaking into the script execution context. + +-- File test.uc -- +export let obj = { foo: true, bar: false }; +-- End -- + +-- Testcase -- +import * as test from "./files/test.uc"; + +printf("%.J\n", [ + type(test.obj), + test.obj.foo +]); +-- End -- + +-- Args -- +-R +-- End -- + +-- Expect stdout -- +[ + "object", + true +] +-- End -- diff --git a/vm.c b/vm.c index 3dd054b3..9488288a 100644 --- a/vm.c +++ b/vm.c @@ -431,7 +431,7 @@ uc_vm_resolve_upval(uc_vm_t *vm, uc_value_t *value) void uc_vm_stack_push(uc_vm_t *vm, uc_value_t *value) { - uc_vector_push(&vm->stack, value); + uc_vector_push(&vm->stack, uc_vm_resolve_upval(vm, value)); if (vm->trace) { fprintf(stderr, " [+%zd] %s\n", From ed5ce8f490188f3c528c7dd5db09ec0470377283 Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Fri, 29 Nov 2024 16:36:53 +0100 Subject: [PATCH 3/3] types: resolve upvalue values in arrays and objects Some objects, such as wildcard module import namespace dictionaries may contain upvalue type values. Extend `ucv_key_get()` to transparently resolve such values before returning them to the caller in order to avoid increasing the refcount of the upvalue itself, leading to a memory leak later on when the VM indirectly dereferences it on upon `uc_vm_stack_push()`, loosing the upvalue object reference itself in the process. This long standing leak was discovered while fixing another upvalue related module import quirk. Signed-off-by: Jo-Philipp Wich --- types.c | 48 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/types.c b/types.c index 9751e24f..26f588e8 100644 --- a/types.c +++ b/types.c @@ -2237,8 +2237,9 @@ uc_value_t * ucv_key_get(uc_vm_t *vm, uc_value_t *scope, uc_value_t *key) { uc_value_t *o, *v = NULL; + bool found = false; + uc_upvalref_t *ref; int64_t idx; - bool found; char *k; if (ucv_type(scope) == UC_ARRAY) { @@ -2247,23 +2248,48 @@ ucv_key_get(uc_vm_t *vm, uc_value_t *scope, uc_value_t *key) if (idx < 0 && idx > INT64_MIN && (uint64_t)llabs(idx) <= ucv_array_length(scope)) idx += ucv_array_length(scope); - if (idx >= 0 && (uint64_t)idx < ucv_array_length(scope)) - return ucv_get(ucv_array_get(scope, idx)); + if (idx >= 0 && (uint64_t)idx < ucv_array_length(scope)) { + v = ucv_array_get(scope, idx); + found = true; + } } - k = ucv_key_to_string(vm, key); + if (!found) { + k = ucv_key_to_string(vm, key); + + for (o = scope; o; o = ucv_prototype_get(o)) { + if (ucv_type(o) != UC_OBJECT) + continue; - for (o = scope; o; o = ucv_prototype_get(o)) { - if (ucv_type(o) != UC_OBJECT) - continue; + v = ucv_object_get(o, k ? k : ucv_string_get(key), &found); - v = ucv_object_get(o, k ? k : ucv_string_get(key), &found); + if (found) + break; + } - if (found) - break; + free(k); } - free(k); + /* Handle upvalue values in objects; under some specific circumstances + objects may contain upvalues, this primarily happens with wildcard module + import namespace dictionaries. */ +#ifdef __clang_analyzer__ + /* Clang static analyzer does not understand that ucv_type(NULL) can't + * possibly yield UC_UPVALUE. Nudge it. */ + if (v != NULL && ucv_type(v) == UC_UPVALUE) +#else + if (ucv_type(v) == UC_UPVALUE) +#endif + { + ref = (uc_upvalref_t *)v; + + if (ref->closed) + return ucv_get(ref->value); + else if (vm) + return ucv_get(vm->stack.entries[ref->slot]); + else + return NULL; + } return ucv_get(v); }