Skip to content

fix: fixing bug with unpacking new eim version on linux - #1498

Open
sigmaaa wants to merge 3 commits into
masterfrom
fix_bug_with_upacking_new_eim
Open

fix: fixing bug with unpacking new eim version on linux#1498
sigmaaa wants to merge 3 commits into
masterfrom
fix_bug_with_upacking_new_eim

Conversation

@sigmaaa

@sigmaaa sigmaaa commented Aug 9, 2026

Copy link
Copy Markdown
Collaborator

Description

Bug
Opening ESP-IDF Terminal after installing EIM via Espressif-IDE could launch the EIM GUI on Linux.

Newer EIM zips ship eim_vX.Y.Z plus an eim symlink. IDE unzip (ZipInputStream) turned that symlink into a tiny text file. On later startup, PATH lookup gave it +x. The activation script then ran eim select …; because eim was not a real binary/symlink, args were not forwarded and the GUI opened by default.

Older zips with only a plain eim binary were fine.

Fix
After unzip, detect that broken eim payload and restore a real symlink to eim_vX.Y.Z (or copy the target if symlinks are unavailable). Prefer the stable eim path for launch. Legacy single-binary packages are left unchanged.

Fixes # (([~>EI-65397])](https://athena.espressif.cn:6565/w/xzzYSdgR))

Type of change

Please delete options that are not relevant.

  • Bug fix (non-breaking change which fixes an issue)

How has this been tested?

  1. Download the latest eim, which provides eim_vX.Y.Z executable -> open esp-idf terminal in the IDE -> no gui EIM should be opened

Download the older eim version without eim_vX.Y.Z executable and repeat step 1

Test Configuration:

  • ESP-IDF Version:
  • OS (Windows,Linux and macOS):

Dependent components impacted by this PR:

  • Component 1
  • Component 2

Checklist

  • PR Self Reviewed
  • Applied Code formatting
  • Added Documentation
  • Added Unit Test
  • Verified on all platforms - Windows,Linux and macOS

Summary by CodeRabbit

Bug Fixes

  • Improved EIM archive extraction security by blocking unsafe path traversal.
  • Restored executable permissions for extracted tools where supported.
  • Improved handling of versioned binaries and symbolic links, including a fallback when links cannot be created.
  • Preserved compatibility with legacy plain-binary archives.
  • Improved reliability for large files and packaged symbolic-link payloads.

@sigmaaa sigmaaa self-assigned this Aug 9, 2026
@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR moves EIM ZIP extraction into EimZipExtractor. The extractor adds traversal protection, executable handling, symlink-payload repair, launch-path selection, and cross-platform tests.

Changes

EIM extraction flow

Layer / File(s) Summary
EIM ZIP extraction and payload repair
bundles/com.espressif.idf.core/src/com/espressif/idf/core/tools/EimZipExtractor.java
Adds ZIP extraction, traversal checks, executable handling, materialized symlink repair, payload detection, and launch-path selection.
Loader delegation
bundles/com.espressif.idf.core/src/com/espressif/idf/core/tools/EimLoader.java
unzip delegates extraction and result selection to EimZipExtractor.extract. Obsolete ZIP imports are removed.
Cross-platform extractor tests
tests/com.espressif.idf.core.test/src/com/espressif/idf/core/tools/test/EimZipExtractorTest.java
Tests legacy binaries, symlink repair, Windows fallback, executable permissions, payload detection, archive selection, and ZIP-generation helpers.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant EimLoader
  participant EimZipExtractor
  participant DestinationDirectory
  EimLoader->>EimZipExtractor: extract(zipPath, destDir)
  EimZipExtractor->>DestinationDirectory: create and materialize ZIP entries
  EimZipExtractor->>DestinationDirectory: repair materialized eim payload
  EimZipExtractor-->>EimLoader: return preferred launch path
Loading

Suggested reviewers: kolipakakondal, andriifilippov

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 17.65% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: fixing Linux extraction for newer EIM versions.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix_bug_with_upacking_new_eim

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
tests/com.espressif.idf.core.test/src/com/espressif/idf/core/tools/test/EimZipExtractorTest.java (1)

83-109: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Add a ZIP traversal regression test.

The new extractor rejects traversal entries, but this test suite does not protect that behavior. Create a ZIP entry such as "../escaped". Assert that EimZipExtractor.extract throws IOException. Assert that no file is created outside the destination.

Proposed test
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+	`@Test`
+	void rejectsZipEntryOutsideDestination() throws Exception
+	{
+		Path zip = tempDir.resolve("traversal.zip");
+		Path dest = tempDir.resolve("out");
+		writeSingleFileZip(zip, "../escaped", "payload");
+
+		assertThrows(IOException.class, () -> EimZipExtractor.extract(zip, dest));
+		assertFalse(Files.exists(tempDir.resolve("escaped")));
+	}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@tests/com.espressif.idf.core.test/src/com/espressif/idf/core/tools/test/EimZipExtractorTest.java`
around lines 83 - 109, Add a regression test in EimZipExtractorTest that creates
a ZIP containing a "../escaped" traversal entry, invokes
EimZipExtractor.extract, and asserts IOException is thrown. Verify afterward
that the escaped path outside the destination does not exist, using the existing
temporary-directory setup and test conventions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@bundles/com.espressif.idf.core/src/com/espressif/idf/core/tools/EimZipExtractor.java`:
- Around line 200-220: Update EimZipExtractor’s archive extraction flow and
resolvePreferredLaunchPath so candidate stable and versioned EIM paths are
tracked only while processing the current ZIP, rather than discovered from all
files in destDir. Exclude pre-existing stable and versioned binaries when
selecting the launch path, preserve firstRegularFile fallback behavior, and add
an update regression test covering a pre-existing EIM file.
- Around line 163-170: Update looksLikeMaterializedSymlinkPayload to apply the
same target validation as repairMaterializedEimSymlink: reject carriage returns
and the ".." target in addition to the existing empty, newline, and
path-separator checks. Reuse the existing validation logic or shared helper so
payload detection and repair accept identical targets.

---

Nitpick comments:
In
`@tests/com.espressif.idf.core.test/src/com/espressif/idf/core/tools/test/EimZipExtractorTest.java`:
- Around line 83-109: Add a regression test in EimZipExtractorTest that creates
a ZIP containing a "../escaped" traversal entry, invokes
EimZipExtractor.extract, and asserts IOException is thrown. Verify afterward
that the escaped path outside the destination does not exist, using the existing
temporary-directory setup and test conventions.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a82a144a-ea30-482b-83ce-76d1702b589f

📥 Commits

Reviewing files that changed from the base of the PR and between c303213 and e5316a5.

📒 Files selected for processing (3)
  • bundles/com.espressif.idf.core/src/com/espressif/idf/core/tools/EimLoader.java
  • bundles/com.espressif.idf.core/src/com/espressif/idf/core/tools/EimZipExtractor.java
  • tests/com.espressif.idf.core.test/src/com/espressif/idf/core/tools/test/EimZipExtractorTest.java

@AndriiFilippov

Copy link
Copy Markdown
Collaborator

@sigmaaa hi !
Tested under:
OS: Windows 11 / Linux ubuntu / Mac arm64
EIM: 0.17.4 / 0.16

EIM archive extraction issue fixed ✅
LGTM 👍

@kolipakakondal please, review

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
tests/com.espressif.idf.core.test/src/com/espressif/idf/core/tools/test/EimZipExtractorTest.java (1)

68-80: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Base fallback assertions on symlink creation outcome.

repairMaterializedEimSymlink() catches symlink creation failures and copies the target on Windows and non-Windows. This test still expects every non-Windows run to create a real Files.isSymbolicLink(eim); run it on a Linux filesystem without symlink support, and the fallback branch is untested. Use a Files.isSymbolicLink(eim)-based branch, or make the symlink creation deterministically fail.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@tests/com.espressif.idf.core.test/src/com/espressif/idf/core/tools/test/EimZipExtractorTest.java`
around lines 68 - 80, Update the assertions in EimZipExtractorTest to branch on
Files.isSymbolicLink(eim) rather than the operating system, validating the
symlink target when creation succeeds and the regular-file contents when
fallback copying occurs. Keep the shared content and executable assertions
appropriate to each outcome.
bundles/com.espressif.idf.core/src/com/espressif/idf/core/tools/EimZipExtractor.java (1)

60-73: 🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

Contain link resolution within destDir.

normalize() is lexical only, while Files.copy, Files.isRegularFile, and subsequent symlink repair operations can follow links before or after the startsWith() check. If destDir or an archive-created parent is a symlink, entries can be extracted or repaired outside destDir. Extract into a fresh real staging directory first, or validate every component and target with LinkOption.NOFOLLOW_LINKS and real-path containment before write/repair operations.

Also applies to extraction at lines 60-80, repair targets at lines 120-141, and looksLikeMaterializedSymlinkPayload at lines 167-187.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@bundles/com.espressif.idf.core/src/com/espressif/idf/core/tools/EimZipExtractor.java`
around lines 60 - 73, Harden EimZipExtractor so extraction and symlink repair
cannot follow links outside destDir: use a fresh real staging directory for
archive writes, or validate every path component and resolved target with
NOFOLLOW_LINKS and real-path containment before any Files.copy, directory
creation, or repair operation. Apply the same containment guarantees to the
extraction flow, repair targets, and looksLikeMaterializedSymlinkPayload,
preserving valid in-destination entries.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@bundles/com.espressif.idf.core/src/com/espressif/idf/core/tools/EimZipExtractor.java`:
- Around line 176-180: Update isSafeSymlinkTargetName to reject Windows-invalid
filename characters, including ?, *, ", <, >, and |, before any path resolution
occurs. Preserve the existing checks for empty names, newlines, carriage
returns, path separators, and "..", ensuring malformed archive symlink targets
are rejected safely.

---

Outside diff comments:
In
`@bundles/com.espressif.idf.core/src/com/espressif/idf/core/tools/EimZipExtractor.java`:
- Around line 60-73: Harden EimZipExtractor so extraction and symlink repair
cannot follow links outside destDir: use a fresh real staging directory for
archive writes, or validate every path component and resolved target with
NOFOLLOW_LINKS and real-path containment before any Files.copy, directory
creation, or repair operation. Apply the same containment guarantees to the
extraction flow, repair targets, and looksLikeMaterializedSymlinkPayload,
preserving valid in-destination entries.

In
`@tests/com.espressif.idf.core.test/src/com/espressif/idf/core/tools/test/EimZipExtractorTest.java`:
- Around line 68-80: Update the assertions in EimZipExtractorTest to branch on
Files.isSymbolicLink(eim) rather than the operating system, validating the
symlink target when creation succeeds and the regular-file contents when
fallback copying occurs. Keep the shared content and executable assertions
appropriate to each outcome.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 785bf035-c6ef-49ae-a96e-16d470af7965

📥 Commits

Reviewing files that changed from the base of the PR and between e5316a5 and 50ae587.

📒 Files selected for processing (2)
  • bundles/com.espressif.idf.core/src/com/espressif/idf/core/tools/EimZipExtractor.java
  • tests/com.espressif.idf.core.test/src/com/espressif/idf/core/tools/test/EimZipExtractorTest.java

Comment on lines +176 to +180
public static boolean isSafeSymlinkTargetName(String target)
{
return !target.isEmpty() && !target.contains("\n") && !target.contains("\r") //$NON-NLS-1$ //$NON-NLS-2$
&& !target.contains("/") && !target.contains("\\") && !target.contains(".."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '--- locate file ---\n'
git ls-files | rg '^bundles/com\.espressif\.idf\.core/src/com/espressif/idf/core/tools/EimZipExtractor\.java$' || true

printf '\n--- outline ---\n'
ast-grep outline bundles/com.espressif.idf.core/src/com/espressif/idf/core/tools/EimZipExtractor.java --view expanded || true

printf '\n--- relevant source ---\n'
sed -n '1,240p' bundles/com.espressif.idf.core/src/com/espressif/idf/core/tools/EimZipExtractor.java

printf '\n--- search symlink handling ---\n'
rg -n "isSafeSymlinkTargetName|createSymbolicLink|Path\.of|resolve\(target\)|IOException|InvalidPathException" bundles/com.espressif.idf.core/src/com/espressif/idf/core/tools/EimZipExtractor.java

Repository: espressif/idf-eclipse-plugin

Length of output: 257


🌐 Web query:

Java Path.of Windows invalid path characters InvalidPathException documentation

💡 Result:

The java.nio.file.InvalidPathException is an unchecked exception thrown when a path string cannot be converted into a Path object [1][2]. On Windows, this commonly occurs when Path.of(String) or Paths.get(String) encounters characters that are illegal in a Windows file system path, or when the path format violates Windows-specific path conventions [1][3]. Key aspects of InvalidPathException and its behavior with Path.of on Windows include: 1. Nature of the Exception: It is a subclass of IllegalArgumentException [1]. It provides the input string, a reason for the rejection, and the index in the string where the error occurred [1][4]. 2. Common Causes on Windows: - Illegal Characters: Windows restricts characters such as <, >, :, ", |, ?, and * in file names (except in specific contexts like drive letters or UNC paths). An error such as "Illegal char <:> at index 2" often indicates a malformed path, such as an absolute path starting with a leading slash (e.g., /C:/...) which the Windows parser does not recognize as a valid root [3][5][6]. - Invisible Characters: Non-printing or zero-width Unicode characters (e.g., U+202A) can sometimes appear in paths copied from Windows UI elements, triggering this exception even if the path appears correct [3]. - Formatting Issues: While Path.of has been updated in newer JDKs to handle long path prefixes like \\?\ and \\?\UNC\ [7], incorrect manual construction of these strings or leading slashes on Windows paths frequently leads to InvalidPathException [6]. When troubleshooting this exception, examine the "index" provided in the exception message to identify exactly where the parser encountered the invalid character or format, and ensure that path strings do not contain unexpected leading slashes or hidden characters when operating on Windows [1][3].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- locate file ---'
git ls-files | rg '^bundles/com\.espressif\.idf\.core/src/com/espressif/idf/core/tools/EimZipExtractor\.java$' || true

printf '%s\n' '--- outline ---'
ast-grep outline bundles/com.espressif.idf.core/src/com/espressif/idf/core/tools/EimZipExtractor.java --view expanded || true

printf '%s\n' '--- relevant source ---'
sed -n '1,240p' bundles/com.espressif.idf.core/src/com/espressif/idf/core/tools/EimZipExtractor.java

printf '%s\n' '--- search symlink handling ---'
rg -n 'isSafeSymlinkTargetName|createSymbolicLink|Path\.of|resolve\(target\)|IOException|InvalidPathException' bundles/com.espressif.idf.core/src/com/espressif/idf/core/tools/EimZipExtractor.java

Repository: espressif/idf-eclipse-plugin

Length of output: 9782


🌐 Web query:

Java 9 Path.of source WindowsPathParser invalidPathCharacters IllegalChar

💡 Result:

The java.nio.file.InvalidPathException: Illegal char error, often seen with Path.of() or Paths.get() on Windows, occurs because the internal sun.nio.fs.WindowsPathParser enforces strict validation of path strings based on Windows file system naming constraints [1][2][3]. The WindowsPathParser uses a reserved set of characters—< > : " | ? *—as well as control characters (ASCII values below 32) that are considered illegal in Windows filenames [3]. When Path.of() or Paths.get() receives a string containing these characters, the parser throws an InvalidPathException [1][4]. Key points regarding this behavior include: 1. Nature of the Exception: The error occurs because the input string is being interpreted as a raw file path, and it contains characters that are invalid for Windows file system objects [3][4]. A common cause is passing a string that is not a valid file path, such as a URI (e.g., classpath:/...), a string with leading/trailing brackets (often from improper Arrays.toString() usage), or a device name (e.g., NUL:) that the parser does not recognize as a valid path prefix [5][6][4]. 2. Role of WindowsPathParser: This internal class is responsible for decomposing path strings into root, type, and path components [7][3]. The isInvalidPathChar method explicitly checks against the restricted character set [3]. 3. Path.of vs. Paths.get: Path.of() was introduced in Java 9 as a preferred, modern alternative to Paths.get() [8][9]. Both methods ultimately rely on the same underlying file system implementation (FileSystems.getDefault().getPath()) and are subject to the same validation logic in WindowsPathParser [10][6][4]. If you encounter this exception, ensure the input string does not contain reserved characters or formatting artifacts, and verify that you are not passing a URI or a non-file-system string directly into a method expecting a file system path [6][4]. If you need to convert a URI, use Path.of(URI.create(yourUriString)) instead of passing the URI string directly to the path constructor [11][9].

Citations:


🌐 Web query:

Java Path.of platform invalid names JavaPathParser InvalidPathException NUL reserved names

💡 Result:

In Java, the Path.of method (and the underlying Path API) utilizes the system-default FileSystem to parse path strings [1][2]. When a path string is provided, the parser validates it against platform-specific constraints [1]. If a string contains illegal characters or is otherwise invalid for the underlying file system, an InvalidPathException is thrown [1][3]. Regarding NUL characters (\u0000): The NUL character is strictly forbidden in path strings across supported platforms [1]. Java explicitly checks for this character during path parsing [4]. For example, in the Unix implementation, the parser performs a specific check for NUL (\u0000) and throws an InvalidPathException if one is encountered [4]. Regarding Reserved Names (e.g., NUL, CON, PRN): The behavior regarding Windows reserved names (such as NUL, CON, AUX, COMx, LPTx) is more nuanced than the handling of the NUL character [5]. 1. Path.of and Related API Validation: While Path.of will throw an InvalidPathException for illegal characters (like colons used in "NUL:" or invalid filename characters like <, >, |, etc.) [6][7][8], it does not automatically reject strings that are simply reserved Windows keywords (like "NUL") [5]. 2. File System Interactions: These reserved names are legacies of DOS/Windows device files [5]. Attempting to use them as file paths may succeed or fail depending on the specific file system and the exact context (e.g., creating a file vs. a directory) [5]. Because they are reserved for system devices, interactions with these paths at the operating system level can lead to "incorrect function" errors or other I/O exceptions rather than an InvalidPathException during the path parsing phase [9]. Summary: - InvalidPathException is primarily thrown for structural issues, such as illegal characters (including NUL bytes) or malformed path syntax [1][3]. - Reserved names (e.g., "NUL") are often accepted as valid Path objects because they are technically valid strings, but they may trigger OS-level errors when actual I/O operations are attempted [5][9].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- inspect repository file header/imports/style ---'
sed -n '1,80p' bundles/com.espressif.idf.core/src/com/espressif/idf/core/tools/EimZipExtractor.java | cat -n

printf '%s\n' '--- count tabs vs spaces in target method region ---'
sed -n '180,210p' bundles/com.espressif.idf.core/src/com/espressif/idf/core/tools/EimZipExtractor.java | cat -n | rg -n $'\t|    ' || true

Repository: espressif/idf-eclipse-plugin

Length of output: 5186


Reject platform-invalid symlink target names before path resolution.

isSafeSymlinkTargetName accepts ?, *, ", <, >, |, and other platform-invalid Windows filename characters. On Windows, destDir.resolve(target).normalize() and Path.of(target) can throw an unchecked parse failure before the symlink-copy fallback runs, so a malformed archive payload aborts extraction. Reject platform-invalid characters in isSafeSymlinkTargetName, or catch InvalidPathException around path resolution and symlink creation.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@bundles/com.espressif.idf.core/src/com/espressif/idf/core/tools/EimZipExtractor.java`
around lines 176 - 180, Update isSafeSymlinkTargetName to reject Windows-invalid
filename characters, including ?, *, ", <, >, and |, before any path resolution
occurs. Preserve the existing checks for empty names, newlines, carriage
returns, path separators, and "..", ensuring malformed archive symlink targets
are rejected safely.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@bundles/com.espressif.idf.core/src/com/espressif/idf/core/tools/EimZipExtractor.java`:
- Around line 108-114: The repair flow in repairMaterializedEimSymlink must
verify that targetPath is also present in extractedFromArchive before restoring
the eim symlink or copy. When the target is absent, reject the payload or
exclude eim from launch candidates, and add a regression test covering an
archive referencing a pre-existing versioned file.
- Around line 56-59: Update EimZipExtractor.extract to inspect every existing
path component from destDir to each archive entry and reject any symbolic link
before Files.createDirectories or Files.copy executes; retain the existing
lexical traversal protection and fail extraction with an appropriate
IOException. Add a regression test using a pre-existing directory symlink
beneath the destination, assert extraction is rejected, and verify the symlink’s
external target remains unchanged.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1a392414-0b00-4094-b008-d8bab7f12527

📥 Commits

Reviewing files that changed from the base of the PR and between 50ae587 and 8a915ae.

📒 Files selected for processing (2)
  • bundles/com.espressif.idf.core/src/com/espressif/idf/core/tools/EimZipExtractor.java
  • tests/com.espressif.idf.core.test/src/com/espressif/idf/core/tools/test/EimZipExtractorTest.java

Comment on lines +56 to +59
public static Path extract(Path zipPath, Path destDir) throws IOException
{
Files.createDirectories(destDir);
Set<Path> extractedFiles = new LinkedHashSet<>();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Reject existing symlink components during extraction.

The lexical check does not stop Files.createDirectories and Files.copy from following an existing directory symlink below destDir. If destDir/plugins links outside destDir, an archive entry named plugins/file passes the check and writes outside the extraction directory.

Reject symlink path components before writing each entry. Add a regression test with a pre-existing directory symlink and verify that its external target remains unchanged.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@bundles/com.espressif.idf.core/src/com/espressif/idf/core/tools/EimZipExtractor.java`
around lines 56 - 59, Update EimZipExtractor.extract to inspect every existing
path component from destDir to each archive entry and reject any symbolic link
before Files.createDirectories or Files.copy executes; retain the existing
lexical traversal protection and fail extraction with an appropriate
IOException. Add a regression test using a pre-existing directory symlink
beneath the destination, assert extraction is rejected, and verify the symlink’s
external target remains unchanged.

Comment on lines +108 to +114
static void repairMaterializedEimSymlink(Path destDir, Collection<Path> extractedFromArchive) throws IOException
{
Path eim = destDir.resolve("eim").normalize(); //$NON-NLS-1$
if (!extractedFromArchive.contains(eim))
{
return;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Require the symlink target to come from the current archive.

extractedFromArchive confirms only that eim came from the archive. It does not confirm that targetPath came from the archive. If the ZIP contains eim with payload eim_v0.17.4 and destDir retains an old eim_v0.17.4, the repair restores a link or copy of the old executable. Launch-path selection then returns that stable eim path.

Require extractedFromArchive.contains(targetPath) before repair. If the target is absent, reject the invalid payload or exclude eim from launch candidates. Add a regression test for an archived payload that references a pre-existing versioned file.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@bundles/com.espressif.idf.core/src/com/espressif/idf/core/tools/EimZipExtractor.java`
around lines 108 - 114, The repair flow in repairMaterializedEimSymlink must
verify that targetPath is also present in extractedFromArchive before restoring
the eim symlink or copy. When the target is absent, reject the payload or
exclude eim from launch candidates, and add a regression test covering an
archive referencing a pre-existing versioned file.

@AndriiFilippov

Copy link
Copy Markdown
Collaborator

Tested with latest changes from Peter in EIM 0.18
LGTM 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants