11 Commits
15 changed files with 387 additions and 26 deletions

No files matched your search

+162
View File
@@ -7,6 +7,8 @@ on:
push:
pull_request:
permissions:
contents: write
jobs:
build-linux24:
@@ -26,6 +28,48 @@ jobs:
run: r2r test/db/cmd
- name: Radare Extras Testing
run: r2r test/db/extras
- name: Package Linux build
run: make -C dist/linux
- name: Verify Linux package
run: |
tar tzvf dist/linux/r2flutter-linux-x86_64.tar.gz
tar tzf dist/linux/r2flutter-linux-x86_64.tar.gz | grep -q 'bin/r2flutter$'
tar tzf dist/linux/r2flutter-linux-x86_64.tar.gz | grep -q 'plugins/core_flutter.so$'
- name: Upload Linux package
uses: actions/upload-artifact@v7
with:
name: r2flutter-linux-x86_64
path: dist/linux/r2flutter-linux-x86_64.tar.gz
if-no-files-found: error
- name: Package Debian build
run: make -C dist/debian
- name: Verify Debian package
shell: bash
run: |
shopt -s nullglob
packages=(dist/debian/r2flutter_*_amd64.deb)
test "${#packages[@]}" -eq 1
package="${packages[0]}"
version="$(./configure -qV)"
test "$(dpkg-deb --field "${package}" Package)" = r2flutter
test "$(dpkg-deb --field "${package}" Version)" = "${version}"
test "$(dpkg-deb --field "${package}" Architecture)" = amd64
test "$(dpkg-deb --field "${package}" Depends)" = radare2
contents="$(dpkg-deb --contents "${package}")"
printf '%s\n' "${contents}"
grep -E '^-.+ root/root .+ \./usr/local/bin/r2flutter$' <<< "${contents}"
plugin=".$(r2 -H R2_LIBR_PLUGINS)/core_flutter.so"
grep -Fq "${plugin}" <<< "${contents}"
make user-uninstall
sudo dpkg --force-depends --install "${package}"
test "$(r2flutter -V)" = "r2flutter ${version}"
test "$(r2 -q -c 'r2flutter -V' --)" = "r2flutter ${version}"
- name: Upload Debian package
uses: actions/upload-artifact@v7
with:
name: r2flutter-debian-amd64
path: dist/debian/r2flutter_*_amd64.deb
if-no-files-found: error
meson-linux24:
name: Meson build on Linux
@@ -63,6 +107,56 @@ jobs:
run: r2r test/db/cmd
- name: Radare Extras Testing
run: r2r test/db/extras
- name: Package macOS build
run: make -C dist/macos
- name: Verify macOS package
run: |
tar tzvf dist/macos/r2flutter-macos.tar.gz
tar tzf dist/macos/r2flutter-macos.tar.gz | grep -q 'bin/r2flutter$'
tar tzf dist/macos/r2flutter-macos.tar.gz | grep -q 'plugins/core_flutter.dylib$'
- name: Upload macOS package
uses: actions/upload-artifact@v7
with:
name: r2flutter-macos
path: dist/macos/r2flutter-macos.tar.gz
if-no-files-found: error
build-windows:
runs-on: windows-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v7
with:
python-version: 3.14.x
- name: Prepare MSVC toolchain
uses: ilammy/msvc-dev-cmd@v1
with:
arch: x64
- name: Install build tools
shell: pwsh
run: python -m pip install meson ninja
- name: Install radare2 ${{ env.R2V }}
uses: radareorg/github-actions@v3
with:
version: ${{ env.R2V }}
from-git: false
- name: Build and package r2flutter
shell: pwsh
run: ./dist/windows/build.ps1
- name: Verify Windows package
shell: pwsh
run: |
Expand-Archive -Path dist/windows/r2flutter-windows-x86_64.zip -DestinationPath check-zip -Force
Get-ChildItem -Recurse check-zip | Select-Object -ExpandProperty FullName
$root = 'check-zip/r2flutter-windows-x86_64'
if (-not (Test-Path "$root/bin/r2flutter.exe")) { throw 'missing r2flutter.exe' }
if (-not (Test-Path "$root/plugins/core_flutter.dll")) { throw 'missing core_flutter.dll' }
- name: Upload Windows package
uses: actions/upload-artifact@v7
with:
name: r2flutter-windows-x86_64
path: dist/windows/r2flutter-windows-x86_64.zip
if-no-files-found: error
r2-xps:
name: Build radare2 with r2flutter XPS
@@ -87,3 +181,71 @@ jobs:
run: |
r2 -q -c 'Lc~r2flutter' -- | grep r2flutter
r2 -q -c 'r2flutter -V' -- | grep 'r2flutter '
check-release:
if: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') }}
needs:
- build-linux24
- meson-linux24
- build-macos
- build-windows
- r2-xps
runs-on: ubuntu-24.04
outputs:
is_release: ${{ steps.tag.outputs.is_release }}
steps:
- name: Check release tag
id: tag
shell: bash
run: |
if [[ "${GITHUB_REF_NAME}" =~ ^[0-9] ]]; then
echo "is_release=yes" >> "$GITHUB_OUTPUT"
else
echo "is_release=no" >> "$GITHUB_OUTPUT"
fi
release:
if: ${{ needs.check-release.outputs.is_release == 'yes' }}
needs: check-release
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Prepare release notes
shell: bash
run: |
tag="${GITHUB_REF_NAME}"
previous_tag="$(git tag --merged "${tag}^" --sort=-version:refname | awk '/^[0-9]/{print; exit}')"
{
echo "# ${tag}"
echo
if [ -n "${previous_tag}" ]; then
echo "## Changes since ${previous_tag}"
echo
git log --pretty=format:'- %s (%h)' "${previous_tag}..${tag}"
else
echo "## Changes"
echo
git log --pretty=format:'- %s (%h)' "${tag}"
fi
echo
} > RELEASE_NOTES.md
- name: Download release artifacts
uses: actions/download-artifact@v8
with:
path: release-artifacts
- name: Create GitHub release
uses: softprops/action-gh-release@v3
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref_name }}
name: ${{ github.ref_name }}
body_path: RELEASE_NOTES.md
generate_release_notes: false
files: |
release-artifacts/r2flutter-linux-x86_64/r2flutter-linux-x86_64.tar.gz
release-artifacts/r2flutter-debian-amd64/r2flutter_*_amd64.deb
release-artifacts/r2flutter-macos/r2flutter-macos.tar.gz
release-artifacts/r2flutter-windows-x86_64/r2flutter-windows-x86_64.zip
Vendored
+5 -5
View File
@@ -127,12 +127,12 @@ done
: ${INSTALL_PROGRAM_STRIP:=${INSTALL} -m 755 -s}
: ${INSTALL_MAN:=${INSTALL} -m 444}
: ${INSTALL_LIB:=${INSTALL} -m 755 -c}
PKGNAME='r2flutter' ; VERSION='0.3.0' ; VERSION_MAJOR=0; VERSION_MINOR=3; VERSION_PATCH=0; VERSION_NUMBER=00300; CONTACT_MAIL="[email protected]" ; CONTACT_NAME="pancake" ; CONTACT="pancake <[email protected]>" ;
PKGNAME='r2flutter' ; VERSION='0.3.6' ; VERSION_MAJOR=0; VERSION_MINOR=3; VERSION_PATCH=6; VERSION_NUMBER=00306; CONTACT_MAIL="[email protected]" ; CONTACT_NAME="pancake" ; CONTACT="pancake <[email protected]>" ;
}
show_usage() {
cat <<EOF2
'configure' configures r2flutter-0.3.0 to adapt to many kinds of systems.
'configure' configures r2flutter-0.3.6 to adapt to many kinds of systems.
Usage: ./configure [OPTION]... [VAR=VALUE]...
@@ -214,10 +214,10 @@ ocho() {
show_version() {
if [ "$QUIET" = 1 ]; then
echo "0.3.0"
echo "0.3.6"
exit 0
fi
echo "r2flutter-0.3.0 configuration script done with acr v2.2.8.
echo "r2flutter-0.3.6 configuration script done with acr v2.2.8.
The 'Free Software Foundation' message is only for autodetection.
Originally written by pancake <nopcode.org>."
exit 0
@@ -246,7 +246,7 @@ case $flag in
show_version ; ;;
-r|--r|--report)
echo "PKGNAME: r2flutter"
echo "VERSION: 0.3.0"
echo "VERSION: 0.3.6"
echo "AUTHOR: pancake"
echo "EMAIL: [email protected]"
echo "LANGS: c"
+1 -1
View File
@@ -1,5 +1,5 @@
PKGNAME r2flutter
VERSION 0.3.0
VERSION 0.3.6
CONTACT pancake ; [email protected]
LANG_C!
+36
View File
@@ -0,0 +1,36 @@
# r2flutter binary release
This package contains:
* `bin/r2flutter` — the standalone command line tool
* `plugins/core_flutter.{so,dylib,dll}` — the radare2 core plugin
## Installing
Copy the tool anywhere in your `$PATH` and drop the plugin into the radare2
plugin directory reported by r2:
```sh
r2 -H R2_USER_PLUGINS # per user, no root needed
r2 -H R2_LIBR_PLUGINS # system wide
```
For example:
```sh
mkdir -p "$(r2 -H R2_USER_PLUGINS)"
cp plugins/core_flutter.* "$(r2 -H R2_USER_PLUGINS)"
cp bin/r2flutter /usr/local/bin
```
On Windows the plugin directory is usually `%HOMEPATH%\.local\share\radare2\plugins`.
## Checking the installation
```sh
r2 -qc 'Lc~r2flutter' --
r2flutter -V
```
The plugin must match the radare2 version it was built against, otherwise r2
refuses to load it.
+13
View File
@@ -0,0 +1,13 @@
PACKAGE=r2flutter
VERSION?=$(shell ../../configure -qV)
DEPENDS=radare2
SECTION=user/shell
PRIORITY=optional
MAINTAINER=pancake <[email protected]>
# arch
UNAMEM=$(shell uname -m)
ifeq ($(UNAMEM),x86_64)
ARCH?=amd64
else
ARCH?=arm64
endif
+30
View File
@@ -0,0 +1,30 @@
include ./CONFIG
PWD=$(shell pwd)
all: deb
deb:
$(MAKE) root
$(MAKE) build
root:
rm -rf root
$(MAKE) -C ../.. install DESTDIR=$(PWD)/root
build:
mkdir -p root/DEBIAN
echo "Package: $(PACKAGE)" > root/DEBIAN/control
echo "Version: $(VERSION)" >> root/DEBIAN/control
echo "Section: $(SECTION)" >> root/DEBIAN/control
echo "Priority: $(PRIORITY)" >> root/DEBIAN/control
echo "Architecture: $(ARCH)" >> root/DEBIAN/control
echo "Depends: $(DEPENDS)" >> root/DEBIAN/control
echo "Maintainer: $(MAINTAINER)" >> root/DEBIAN/control
echo "Description: r2flutter plugin for radare2" >> root/DEBIAN/control
dpkg-deb --root-owner-group --build root $(PACKAGE)_$(VERSION)_$(ARCH).deb
clean:
rm -rf root *.deb
.PHONY: all deb root build clean
+18
View File
@@ -0,0 +1,18 @@
ROOT := $(CURDIR)/r2flutter-linux-x86_64
ARCHIVE := $(CURDIR)/r2flutter-linux-x86_64.tar.gz
STRIP ?= strip
all:
rm -rf $(ROOT) $(ARCHIVE)
mkdir -p $(ROOT)/bin $(ROOT)/plugins
cp ../../bin/r2flutter $(ROOT)/bin/
cp ../../src/r2/core_flutter.so $(ROOT)/plugins/
cp ../README.md $(ROOT)/
$(STRIP) --strip-all $(ROOT)/bin/r2flutter
$(STRIP) --strip-unneeded $(ROOT)/plugins/core_flutter.so
tar -C $(CURDIR) -czf $(ARCHIVE) r2flutter-linux-x86_64
clean:
rm -rf $(ROOT) $(ARCHIVE)
.PHONY: all clean
+20
View File
@@ -0,0 +1,20 @@
ROOT := $(CURDIR)/r2flutter-macos
ARCHIVE := $(CURDIR)/r2flutter-macos.tar.gz
STRIP ?= strip
all:
rm -rf $(ROOT) $(ARCHIVE)
mkdir -p $(ROOT)/bin $(ROOT)/plugins
cp ../../bin/r2flutter $(ROOT)/bin/
cp ../../src/r2/core_flutter.dylib $(ROOT)/plugins/
cp ../README.md $(ROOT)/
$(STRIP) -x $(ROOT)/bin/r2flutter
$(STRIP) -x $(ROOT)/plugins/core_flutter.dylib
codesign -f -s - $(ROOT)/bin/r2flutter
codesign -f -s - $(ROOT)/plugins/core_flutter.dylib
tar -C $(CURDIR) -czf $(ARCHIVE) r2flutter-macos
clean:
rm -rf $(ROOT) $(ARCHIVE)
.PHONY: all clean
+15
View File
@@ -0,0 +1,15 @@
$ErrorActionPreference = 'Stop'
meson setup build-windows --buildtype=release
meson compile -C build-windows
$root = 'dist/windows/r2flutter-windows-x86_64'
$archive = 'dist/windows/r2flutter-windows-x86_64.zip'
Remove-Item -Recurse -Force $root -ErrorAction SilentlyContinue
Remove-Item -Force $archive -ErrorAction SilentlyContinue
New-Item -ItemType Directory -Force $root/bin | Out-Null
New-Item -ItemType Directory -Force $root/plugins | Out-Null
Copy-Item build-windows/r2flutter.exe $root/bin/
Copy-Item build-windows/core_flutter.dll $root/plugins/
Copy-Item dist/README.md $root/
Compress-Archive -Path $root -DestinationPath $archive -Force
+2 -2
View File
@@ -1,9 +1,9 @@
#ifndef R2FLUTTER_VERSION_H
#define R2FLUTTER_VERSION_H
#define R2FLUTTER_VERSION "0.3.0"
#define R2FLUTTER_VERSION "0.3.6"
#define R2FLUTTER_VERSION_MAJOR 0
#define R2FLUTTER_VERSION_MINOR 3
#define R2FLUTTER_VERSION_PATCH 0
#define R2FLUTTER_VERSION_PATCH 6
#endif
+46 -4
View File
@@ -1,18 +1,47 @@
project(
'r2flutter',
'c',
version : '0.3.0',
meson_version : '>=0.55.0',
version : '0.3.6',
meson_version : '>=0.56.0',
default_options : ['warning_level=2', 'werror=false']
)
cc = meson.get_compiler('c')
r2 = find_program('r2', required: true)
r2_cflags_res = run_command(r2, '-H', 'R2_CFLAGS', check: true)
r2_ldflags_res = run_command(r2, '-H', 'R2_LDFLAGS', check: true)
r2_libs_res = run_command(r2, '-H', 'R2_LIBS', check: true)
r2_plugdir_res = run_command(r2, '-H', 'R2_LIBR_PLUGINS', check: false)
r2_compile_args = r2_cflags_res.stdout().strip().split()
r2_link_args = r2_ldflags_res.stdout().strip().split() + r2_libs_res.stdout().strip().split()
r2_plugdir = r2_plugdir_res.stdout().strip()
if r2_plugdir == ''
r2_plugdir = join_paths(get_option('prefix'), get_option('libdir'), 'radare2', 'last')
endif
# r2 -H always reports gcc style flags, msvc needs its own spelling for them
if cc.get_argument_syntax() == 'msvc'
msvc_link_args = []
foreach flag : r2_link_args
if flag.startswith('-L')
msvc_link_args += '/LIBPATH:' + flag.substring(2)
elif flag.startswith('-l')
msvc_link_args += flag.substring(2) + '.lib'
else
msvc_link_args += flag
endif
endforeach
r2_link_args = msvc_link_args
# posix names like strdup are available, just noisy without this
r2_compile_args += ['-D_CRT_SECURE_NO_WARNINGS', '-D_CRT_NONSTDC_NO_DEPRECATE']
endif
r_core_dep = declare_dependency(
compile_args: r2_cflags_res.stdout().strip().split(),
link_args: r2_ldflags_res.stdout().strip().split() + r2_libs_res.stdout().strip().split(),
compile_args: r2_compile_args,
link_args: r2_link_args,
)
r2flutter_inc = include_directories('include')
@@ -61,4 +90,17 @@ r2flutter_cli = executable(
install: true,
)
# The radare2 core plugin, loaded by r2 as core_flutter.{so,dylib,dll}
core_flutter = shared_module(
'core_flutter',
'src/r2/core_flutter.c',
'src/r2/flutter_analysis.c',
name_prefix: '',
include_directories: r2flutter_inc,
link_with: r2flutter_static,
dependencies: r_core_dep,
install: true,
install_dir: r2_plugdir,
)
test('r2flutter-version', r2flutter_cli, args: ['-V'])
+13 -2
View File
@@ -179,13 +179,24 @@ static FILE *open_payload_temp(char **out_path) {
FILE *out = try_open_temp_path (r_file_temp ("r2flutter-dart-app-snap"), out_path);
if (!out) {
char *name = r_str_newf ("r2flutter-dart-app-snap.%" PFMT64x, (ut64)r_time_now ());
char *path = name? r_file_new (P_tmpdir, name, NULL): NULL;
char *tmpdir = r_file_tmpdir ();
char *path = (name && tmpdir)? r_file_new (tmpdir, name, NULL): NULL;
free (tmpdir);
free (name);
out = try_open_temp_path (path, out_path);
}
return out;
}
// msvc has no fseeko, but it ships an equivalent 64bit seek
static bool payload_seek(FILE *f, ut64 off) {
#if defined(_MSC_VER)
return _fseeki64 (f, (__int64)off, SEEK_SET) == 0;
#else
return fseeko (f, (off_t)off, SEEK_SET) == 0;
#endif
}
char *dart_app_extract_payload(const char *path, const DartAppEmbeddedPayload *payload) {
if (R_STR_ISEMPTY (path) || !payload || !payload->payload_size) {
return NULL;
@@ -202,7 +213,7 @@ char *dart_app_extract_payload(const char *path, const DartAppEmbeddedPayload *p
fclose (in);
return NULL;
}
bool ok = fseeko (in, (off_t)payload->payload_offset, SEEK_SET) == 0;
bool ok = payload_seek (in, payload->payload_offset);
ut64 remaining = payload->payload_size;
ut8 buf[65536];
while (ok && remaining > 0) {
+24 -10
View File
@@ -388,6 +388,7 @@ typedef struct {
// handful of clusters. Their readers are gated on this flag; everything
// else is shared.
bool legacy_format;
bool shift1_format;
bool closure_variable;
// every CID this layout defines, indexed by kind; -1 when the kind is absent
int by_kind[DART_CID_KIND_COUNT];
@@ -462,6 +463,7 @@ static ModernCidCache modern_cid_cache_init(const DartVerLayout *layout) {
.typed_data_internal_limit = dart_cid_typed_data_limit (layout),
.typed_data_stride = dart_cid_typed_data_stride (layout),
.legacy_format = modern_layout_is_legacy (layout),
.shift1_format = layout && layout->tag_style == DART_TAG_STYLE_CID_SHIFT1,
.closure_variable = layout && layout->closure_variable,
};
for (int kind = 0; kind < DART_CID_KIND_COUNT; kind++) {
@@ -980,8 +982,11 @@ static ModernFillSpec modern_get_fill_spec(const ModernCidCache *cids, int cid)
if (cids->closure_variable && modern_cid_eq (cid, cids->closure)) {
return modern_fill_spec_kind (MODERN_FILL_CLOSURE);
}
if (modern_cid_eq (cid, cids->patch_class)) {
// FullAOT PatchClass layout differs across snapshot families.
return modern_fill_spec_refs ((cids->legacy_format || cids->shift1_format)? 3: 2);
}
static const ModernFillSpecRule rules[] = {
{ DART_CID_PATCH_CLASS, MODERN_FILL_REFS, 2, -1, -1, 0, { 0 } },
{ DART_CID_TYPE_PARAMETERS, MODERN_FILL_REFS, 4, -1, -1, 0, { 0 } },
{ DART_CID_CLOSURE_DATA, MODERN_FILL_REFS, 2, -1, -1, 1, { MODERN_SCALAR_UNSIGNED } },
{ DART_CID_FFI_TRAMPOLINE_DATA, MODERN_FILL_REFS, 4, -1, -1, 2, { MODERN_SCALAR_TAGGED32, MODERN_SCALAR_UINT8 } },
@@ -1046,8 +1051,6 @@ static ModernFillSpec modern_get_fill_spec(const ModernCidCache *cids, int cid)
// than the newer format the table above encodes. Verified against the Dart
// 2.18 AOT (kFullAOT, PRODUCT) serializer in runtime/vm/app_snapshot.cc.
static const ModernFillSpecRule legacy_rules[] = {
// PatchClass::to_snapshot stops at script_ in AOT: 3 refs, no scalars.
{ DART_CID_PATCH_CLASS, MODERN_FILL_REFS, 3, -1, -1, 0, { 0 } },
// FfiTrampolineData: ReadFromTo (4) + ReadUnsigned (callback_id).
{ DART_CID_FFI_TRAMPOLINE_DATA, MODERN_FILL_REFS, 4, -1, -1, 1, { MODERN_SCALAR_UNSIGNED } },
// Type: ReadFromTo (3) + ReadUnsigned (type_class_id) + Read<uint8_t>.
@@ -1987,14 +1990,19 @@ static bool modern_resolver_read_library_fill(ModernWalk *w, ClusterStream *s, c
static bool modern_resolver_read_patch_class_fill(ModernWalk *w, ClusterStream *s, const ModernClusterMeta *meta) {
ModernRefResolver *resolver = (ModernRefResolver *)w->user;
const ModernFillSpec spec = modern_get_fill_spec (&w->cids, meta->cid);
ut64 ref = meta->start_ref;
for (ut64 j = 0; j < meta->count; j++, ref++) {
ut64 wrapped_ref = 0;
ut64 script_ref = 0;
if (!cs_read_ref_id (s, &wrapped_ref) || !cs_read_ref_id (s, &script_ref)) {
return false;
for (int k = 0; k < spec.num_refs; k++) {
ut64 rv = 0;
if (!cs_read_ref_id (s, &rv)) {
return false;
}
if (!k) {
wrapped_ref = rv;
}
}
(void)script_ref;
if (ref < resolver->refs_count) {
resolver->patch_wrapped_ref[ref] = wrapped_ref;
}
@@ -4982,12 +4990,18 @@ static bool modern_name_scan_read_library(ModernWalk *w, ClusterStream *s, const
static bool modern_name_scan_read_patch_class(ModernWalk *w, ClusterStream *s, const ModernClusterMeta *m) {
ModernNameScanWalk *u = (ModernNameScanWalk *)w->user;
const ModernFillSpec spec = modern_get_fill_spec (&w->cids, m->cid);
ut64 ref = m->start_ref;
for (ut64 j = 0; j < m->count; j++, ref++) {
ut64 wrapped_ref = 0;
ut64 script_ref = 0;
if (!cs_read_ref_id (s, &wrapped_ref) || !cs_read_ref_id (s, &script_ref)) {
return false;
for (int k = 0; k < spec.num_refs; k++) {
ut64 rv = 0;
if (!cs_read_ref_id (s, &rv)) {
return false;
}
if (!k) {
wrapped_ref = rv;
}
}
if (ref < u->refs_count) {
u->patch_wrapped_ref[ref] = wrapped_ref;
+1 -1
View File
@@ -377,7 +377,7 @@ void collect_data_names_with_r2(DartCtx *ctx, ut64 data_image_base, ut64 data_im
continue;
}
char *line, *saveptr = NULL;
for (line = strtok_r (out, "\n", &saveptr); line; line = strtok_r (NULL, "\n", &saveptr)) {
for (line = r_str_tok_r (out, "\n", &saveptr); line; line = r_str_tok_r (NULL, "\n", &saveptr)) {
if (!r_str_startswith (line, "0x")) {
continue;
}
+1 -1
View File
@@ -359,7 +359,7 @@ static void sbom_scan_pubspec_lock(RList *components, const char *path) {
bool in_packages = false;
char *current = NULL;
char *saveptr = NULL;
for (char *line = strtok_r (yaml, "\n", &saveptr); line; line = strtok_r (NULL, "\n", &saveptr)) {
for (char *line = r_str_tok_r (yaml, "\n", &saveptr); line; line = r_str_tok_r (NULL, "\n", &saveptr)) {
if (!strcmp (line, "packages:")) {
in_packages = true;
continue;