fix(android): make JSInjector replace first <head> only #6895
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
If an HTML page (local or proxied) contains more than one
<head>
or</head>
string, they will all be replaced. While these should normally be escaped as<head>
in HTML, it is possible that an inline script tag could correctly include this string. This is currently the case for calendly.com, where they have an inline script tag that injects additional content into the<head>
.When JSInjector attempts to insert the native bridge into this page, it will replace all instances of the string, instead of just the first instance (the actual tag). This PR changes it to use
String.replaceFirst
, which accepts a regex pattern and match. As<head>
and</head>
are safe to use in Regex, nothing needs to be done to them, however the native bridge includes JS templates like${Date.now()}
, and${...}
will reference a matched group if used in the replacement string. This escapes${
to be\${
so that it isn't used as a match group.I have pushed a simple reproduction to https://github.com/SpenserJ/capacitor/tree/repro/android-duplicate-head-injection, which should display an alert box with
<head>
, but without this patch it will corrupt the HTML and leave a);
visible at the bottom of the page with no alert shown.npm ci
npx cap sync
npx cap open android
and launch the app on your device<head>
✅./patches
to anything else, and then runningnpm ci
again);