Skip to content

Rethink image parsing logic#14496

Merged
OneBlue merged 13 commits intofeature/wsl-for-appsfrom
user/oneblue/parse-image
Mar 24, 2026
Merged

Rethink image parsing logic#14496
OneBlue merged 13 commits intofeature/wsl-for-appsfrom
user/oneblue/parse-image

Conversation

@OneBlue
Copy link
Collaborator

@OneBlue OneBlue commented Mar 21, 2026

Summary of the Pull Request

This change fixes various issues with PullImage() not correctly handling the reference format. Most notably:

wslc pull debian would pull every single image in the debian repo. Now the tag is defaulted to latest if not specified.

PR Checklist

  • Closes: Link to issue #xxx
  • Communication: I've discussed this with core contributors already. If work hasn't been agreed, this work might be rejected
  • Tests: Added/updated if needed and all pass
  • Localization: All end user facing strings can be localized
  • Dev docs: Added/updated if needed
  • Documentation updated: If checked, please file a pull request on our docs repo and link it here: #xxx

Detailed Description of the Pull Request / Additional comments

Validation Steps Performed

@OneBlue OneBlue requested a review from a team as a code owner March 21, 2026 02:18
Copilot AI review requested due to automatic review settings March 21, 2026 02:18
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR improves WSLA image reference handling by centralizing image-reference parsing and fixing PullImage() behavior when no tag is specified (defaulting to latest instead of pulling all tags).

Changes:

  • Moved image reference parsing into wsl::windows::common::wslutil::ParseImage() with support for tags, digests, and registry ports.
  • Updated WSLASession::PullImage() to default missing tags to latest, and switched other call sites to the shared parser.
  • Added tests for image parsing and added (currently skipped) advanced pull scenarios.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
test/windows/WSLATests.cpp Adds ImageParsing coverage and an advanced pull test (currently unconditionally skipped).
src/windows/wslasession/WSLASession.cpp Uses the shared parser; defaults missing pull tags to latest.
src/windows/common/wslutil.h Declares wslutil::ParseImage().
src/windows/common/wslutil.cpp Implements wslutil::ParseImage() to correctly split repo vs tag/digest (handling registry ports and digests).

// and lookup corresponding digest from the map
auto repoName = ParseImage(tag).first;
auto repoName = wslutil::ParseImage(tag).first;
size_t colonPos = tag.find(':');
Copy link

Copilot AI Mar 21, 2026

Choose a reason for hiding this comment

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

In ListImages(), colonPos is now unused after switching to wslutil::ParseImage(tag).first. This will trigger an unused-local warning (and may break builds if warnings are treated as errors). Remove colonPos or use it for the intended logic.

Suggested change
size_t colonPos = tag.find(':');

Copilot uses AI. Check for mistakes.
@OneBlue OneBlue changed the title User/oneblue/parse image Rethink image parsing logic Mar 23, 2026
@kevpar
Copy link
Member

kevpar commented Mar 23, 2026

Does this supersede #14484 ?

Copilot AI review requested due to automatic review settings March 23, 2026 18:36
@OneBlue
Copy link
Collaborator Author

OneBlue commented Mar 23, 2026

Does this supersede #14484 ?

It does indeed !

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

RETURN_HR_IF_NULL(E_POINTER, ImageUri);

auto [repo, tag] = ParseImage(ImageUri);
auto [repo, tag] = wslutil::ParseImage(ImageUri);
Copy link
Member

Choose a reason for hiding this comment

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

Suggest renaming tag to tagOrDigest, and do the same in the Docker client PullImage signature.

@kevpar
Copy link
Member

kevpar commented Mar 23, 2026

As an aside, I noticed we are implicitly prepending library here: https://github.com/microsoft/WSL/blob/feature/wsl-for-apps/src/windows/wslasession/DockerHTTPClient.cpp#L124

I don't think this is correct to do other than for Docker Hub images. Has image pull been tested with other registries?

Copilot AI review requested due to automatic review settings March 23, 2026 22:58
@OneBlue
Copy link
Collaborator Author

OneBlue commented Mar 23, 2026

As an aside, I noticed we are implicitly prepending library here: https://github.com/microsoft/WSL/blob/feature/wsl-for-apps/src/windows/wslasession/DockerHTTPClient.cpp#L124

I don't think this is correct to do other than for Docker Hub images. Has image pull been tested with other registries?

We don't support custom registries yet, but added a TODO to track that.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.

}

auto lock = m_lock.lock_shared();

Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

PullImage() dereferences m_dockerClient without checking it has a value. Since Terminate() resets m_dockerClient, callers that invoke PullImage() after termination (or on a partially-initialized/failed session) can hit a crash/UB here. Add the same invalid-state guard used by the other image APIs (e.g., THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), !m_dockerClient.has_value());) after taking the shared lock and before calling through it.

Suggested change
THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), !m_dockerClient.has_value());

Copilot uses AI. Check for mistakes.
Copilot AI review requested due to automatic review settings March 24, 2026 01:47
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 5 comments.

VERIFY_ARE_EQUAL(expectedError, comError->Message.get());
}

// Validat that PullImage() returns the appropriate error if the session is terminated.
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

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

Typo in comment: "Validat" should be "Validate".

Suggested change
// Validat that PullImage() returns the appropriate error if the session is terminated.
// Validate that PullImage() returns the appropriate error if the session is terminated.

Copilot uses AI. Check for mistakes.
Comment on lines +1177 to +1178
std::string identifier = "([a-f0-9]{64})";
std::string shortIdentifier = "([a-f0-9]{6,64})";
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

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

BuildImageReferenceRegex() declares identifier and shortIdentifier but never uses them. With /WX enabled in the build, this will fail compilation due to unreferenced local variable warnings. Remove these variables or use them in the constructed regex.

Suggested change
std::string identifier = "([a-f0-9]{64})";
std::string shortIdentifier = "([a-f0-9]{6,64})";

Copilot uses AI. Check for mistakes.
Comment on lines +302 to +312
RETURN_HR_IF_NULL(E_POINTER, Image);

auto lock = m_lock.lock_shared();
THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), !m_dockerClient.has_value());

auto [repo, tagOrDigest] = wslutil::ParseImage(Image);

if (!tagOrDigest.has_value())
{
tagOrDigest = "latest";
}
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

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

WSLASession::PullImage() validates Image != nullptr but does not enforce WSLA_MAX_IMAGE_NAME_LENGTH like other image APIs (e.g., ImportImage, InspectImage). Since this now runs a fairly complex std::regex parse, a very long input could cause unnecessary CPU/memory usage. Add a length check (returning E_INVALIDARG) before calling wslutil::ParseImage.

Copilot uses AI. Check for mistakes.
}
}

std::regex BuildImageReferenceRegex()
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

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

BuildImageReferenceRegex() is defined in the global namespace even though it appears to be a file-local helper. Consider moving it into an anonymous namespace or making it static to avoid exporting an unintended global symbol.

Suggested change
std::regex BuildImageReferenceRegex()
static std::regex BuildImageReferenceRegex()

Copilot uses AI. Check for mistakes.

THROW_HR_IF_MSG(E_UNEXPECTED, !repo.matched, "Unexpected regex match. Input: %hs", Input.c_str());

if (digest.matched) // <repo>:[tag]@<digest] (If both digest and tag are specified, digest takes precedence).
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

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

Minor typo in comment: the reference format example has mismatched brackets (<repo>:[tag]@<digest]). Update it to a correctly bracketed form to avoid confusion.

Suggested change
if (digest.matched) // <repo>:[tag]@<digest] (If both digest and tag are specified, digest takes precedence).
if (digest.matched) // <repo>:[tag]@<digest> (If both digest and tag are specified, digest takes precedence).

Copilot uses AI. Check for mistakes.
@OneBlue OneBlue merged commit 72295b8 into feature/wsl-for-apps Mar 24, 2026
7 checks passed
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.

4 participants