feat(libSceNKWebKit): implement WTF::mimeTypeFromDataURL and URL::stringCenterEllipsizedToLength

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
This commit is contained in:
AshwinandClaude Sonnet 5.5 committed 2026-11-01 20:21:26 +05:30
1 parent e450145140
commit dd166cdd67
6 files changed
+129 -13

No files matched your search

-8
View File
@@ -19408,10 +19408,6 @@ int APS5_VABI _ZN3WTF19isCompilationThreadEv() {
NotImplemented_nid_no_patch(__func__);
}
int APS5_VABI _ZN3WTF19mimeTypeFromDataURLENS_10StringViewE() {
NotImplemented_nid_no_patch(__func__);
}
int APS5_VABI _ZN3WTF19numGraphemeClustersENS_10StringViewE() {
NotImplemented_nid_no_patch(__func__);
}
@@ -36584,10 +36580,6 @@ int APS5_VABI _ZNK3WTF3URL24strippedForUseAsReferrerEv() {
NotImplemented_nid_no_patch(__func__);
}
int APS5_VABI _ZNK3WTF3URL30stringCenterEllipsizedToLengthEj() {
NotImplemented_nid_no_patch(__func__);
}
int APS5_VABI _ZNK3WTF3URL4dumpERNS_11PrintStreamE() {
NotImplemented_nid_no_patch(__func__);
}
@@ -1821,7 +1821,6 @@ int APS5_VABI _ZN3WTF19ParallelEnvironment7executeEPv();
int APS5_VABI _ZN3WTF19ParallelEnvironmentC1EPFvPvEmi();
int APS5_VABI _ZN3WTF19ParallelEnvironmentC2EPFvPvEmi();
int APS5_VABI _ZN3WTF19isCompilationThreadEv();
int APS5_VABI _ZN3WTF19mimeTypeFromDataURLENS_10StringViewE();
int APS5_VABI _ZN3WTF19numGraphemeClustersENS_10StringViewE();
int APS5_VABI _ZN3WTF20ConcurrentPtrHashSet15deleteOldTablesEv();
int APS5_VABI _ZN3WTF20ConcurrentPtrHashSet5clearEv();
@@ -6140,7 +6139,6 @@ int APS5_VABI _ZNK3WTF3URL17lastPathComponentEv();
int APS5_VABI _ZNK3WTF3URL19protocolHostAndPortEv();
int APS5_VABI _ZNK3WTF3URL21truncatedForUseAsBaseEv();
int APS5_VABI _ZNK3WTF3URL24strippedForUseAsReferrerEv();
int APS5_VABI _ZNK3WTF3URL30stringCenterEllipsizedToLengthEj();
int APS5_VABI _ZNK3WTF3URL4dumpERNS_11PrintStreamE();
int APS5_VABI _ZNK3WTF3URL4userEv();
int APS5_VABI _ZNK3WTF3URL8passwordEv();
@@ -208,6 +208,8 @@ bool APS5_VABI _ZNK3WTF24TimeWithDynamicClockTypegeERKS0_(const WTF::TimeWithDyn
bool APS5_VABI _ZNK3WTF24TimeWithDynamicClockTypegtERKS0_(const WTF::TimeWithDynamicClockType* self, const WTF::TimeWithDynamicClockType& other);
bool APS5_VABI _ZNK3WTF24TimeWithDynamicClockTypeleERKS0_(const WTF::TimeWithDynamicClockType* self, const WTF::TimeWithDynamicClockType& other);
WTF::Seconds APS5_VABI _ZNK3WTF24TimeWithDynamicClockTypemiERKS0_(const WTF::TimeWithDynamicClockType* self, const WTF::TimeWithDynamicClockType& other);
NKWebKit::WtfAbi::String APS5_VABI _ZN3WTF19mimeTypeFromDataURLENS_10StringViewE(NKWebKit::WtfAbi::StringView dataURL);
NKWebKit::WtfAbi::String APS5_VABI _ZNK3WTF3URL30stringCenterEllipsizedToLengthEj(const NKWebKit::WtfAbi::URL* self, unsigned length);
bool APS5_VABI _ZNK3WTF3URL10protocolIsENS_10StringViewE(const NKWebKit::WtfAbi::URL* self, NKWebKit::WtfAbi::StringView protocol);
NKWebKit::WtfAbi::StringView APS5_VABI _ZNK3WTF3URL11encodedUserEv(const NKWebKit::WtfAbi::URL* self);
bool APS5_VABI _ZNK3WTF3URL12isAboutBlankEv(const NKWebKit::WtfAbi::URL* self);
@@ -916,6 +916,41 @@ StringView ViewWithoutFragment(const URL& url) {
return Slice(view, 0, std::min(url.queryEnd, view.length));
}
std::size_t FindUnit(StringView view, char16_t value, unsigned start) {
for (unsigned i = start; i < view.length; ++i) {
if (Unit(view, i) == value) return i;
}
return NotFound;
}
StringView LeftView(StringView view, unsigned length) {
return Slice(view, 0, length);
}
StringView RightView(StringView view, unsigned length) {
return Slice(view, view.length - length, length);
}
String ConcatViews(const StringView* parts, unsigned count) {
std::size_t total = 0;
bool is8Bit = true;
for (unsigned i = 0; i < count; ++i) {
total += parts[i].length;
is8Bit &= parts[i].is8Bit;
}
if (total > MaxStringLength) throw std::length_error("WTF string exceeds maximum length");
void* data;
auto* impl = NewImpl(static_cast<unsigned>(total), is8Bit, data);
unsigned offset = 0;
for (unsigned i = 0; i < count; ++i) {
for (unsigned j = 0; j < parts[i].length; ++j, ++offset) {
if (is8Bit) static_cast<unsigned char*>(data)[offset] = static_cast<unsigned char>(Unit(parts[i], j));
else static_cast<char16_t*>(data)[offset] = Unit(parts[i], j);
}
}
return String(impl);
}
} // namespace
extern "C" {
@@ -1022,4 +1057,20 @@ bool APS5_VABI _ZN3WTF22protocolIsInHTTPFamilyENS_10StringViewE(StringView view)
return Unit(view, 4) == ':' || ((Unit(view, 4) | 32) == 's' && view.length >= 6 && Unit(view, 5) == ':');
}
String APS5_VABI _ZN3WTF19mimeTypeFromDataURLENS_10StringViewE(StringView dataURL) {
auto index = FindUnit(dataURL, u';', 5);
if (index == NotFound) index = FindUnit(dataURL, u',', 5);
if (index == NotFound) return String(EmptyImpl());
if (index == 5) return String(CopyImpl({"text/plain", 10, true}));
return String(ConvertCase(Slice(dataURL, 5, static_cast<unsigned>(index - 5)), true));
}
String APS5_VABI _ZNK3WTF3URL30stringCenterEllipsizedToLengthEj(const URL* self, unsigned length) {
const auto& url = Checked(self);
auto view = View(url.impl);
if (view.length <= length) return String(Retain(url.impl));
const StringView parts[] = {LeftView(view, length / 2 - 1), {"...", 3, true}, RightView(view, length / 2 - 2)};
return ConcatViews(parts, 3);
}
}
@@ -809,6 +809,80 @@ const auto JSRealloc = &_ZN3WTF14jsValueReallocEPvm;
std::string ViewText(StringView view) { return Bytes(ViewUTF8(&view, 1)); }
const auto URLEllipsize = &_ZNK3WTF3URL30stringCenterEllipsizedToLengthEj;
const auto DataURLMime = &_ZN3WTF19mimeTypeFromDataURLENS_10StringViewE;
bool Is8Bit(const String& value) { return value.impl && (value.impl->hashAndFlags & 4); }
StringView ViewOf(const String& value) {
return {value.impl->data, value.impl->length, !!(value.impl->hashAndFlags & 4)};
}
StringView Literal(const char* text) { return {text, static_cast<unsigned>(std::strlen(text)), true}; }
void TestURLStringHelpers() {
auto narrow = FromUTF8Z(U8("http://example.com/abcdefghij"));
URL narrowURL{narrow.impl, 0, 0, 0, 0, 0, 0, 0, 0};
for (unsigned length : {29U, 30U, 40U, 0xFFFFFFFFU}) {
auto same = URLEllipsize(&narrowURL, length);
Check(same.impl == narrow.impl && narrow.impl->refCount == 4);
}
Check(narrow.impl->refCount == 2);
Text(URLEllipsize(&narrowURL, 28), "http://exampl...m/abcdefghij");
Text(URLEllipsize(&narrowURL, 10), "http...hij");
Text(URLEllipsize(&narrowURL, 11), "http...hij");
Text(URLEllipsize(&narrowURL, 6), "ht...j");
Text(URLEllipsize(&narrowURL, 5), "h...");
Text(URLEllipsize(&narrowURL, 4), "h...");
Text(URLEllipsize(&narrowURL, 3), "...");
Text(URLEllipsize(&narrowURL, 2), "...");
Text(URLEllipsize(&narrowURL, 1), "http://example.com/abcdefghij...");
Text(URLEllipsize(&narrowURL, 0), "http://example.com/abcdefghij...");
Check(Is8Bit(URLEllipsize(&narrowURL, 10)) && Is8Bit(URLEllipsize(&narrowURL, 3)));
Check(URLEllipsize(&narrowURL, 10).impl != narrow.impl);
auto wide = Create16(u"http://wide.test/path", 21);
URL wideURL{wide.impl, 0, 0, 0, 0, 0, 0, 0, 0};
Check(URLEllipsize(&wideURL, 21).impl == wide.impl);
auto wideShort = URLEllipsize(&wideURL, 10);
Text(wideShort, "http...ath");
Check(!Is8Bit(wideShort));
auto wideDots = URLEllipsize(&wideURL, 3);
Text(wideDots, "...");
Check(!Is8Bit(wideDots));
auto wideLong = URLEllipsize(&wideURL, 1);
Text(wideLong, "http://wide.test/path...");
Check(!Is8Bit(wideLong));
URL absent{};
Check(URLEllipsize(&absent, 0).impl == nullptr && URLEllipsize(&absent, 10).impl == nullptr);
auto empty = Create8(U8(""), 0);
URL emptyURL{empty.impl, 0, 0, 0, 0, 0, 0, 0, 0};
Check(URLEllipsize(&emptyURL, 0).impl == empty.impl && URLEllipsize(&emptyURL, 5).impl == empty.impl);
Throws([&] { URLEllipsize(nullptr, 10); });
Text(DataURLMime(Literal("data:text/HTML;base64,x")), "text/html");
Text(DataURLMime(Literal("data:Text/X,y")), "text/x");
Text(DataURLMime(Literal("data:,x")), "text/plain");
Text(DataURLMime(Literal("data:;base64,x")), "text/plain");
Check(Is8Bit(DataURLMime(Literal("data:,x"))));
Text(DataURLMime(Literal("data:a,b;c")), "a,b");
Text(DataURLMime(Literal("data:text/plain")), "");
Text(DataURLMime(Literal("data:")), "");
Text(DataURLMime(Literal("data")), "");
Text(DataURLMime(Literal("")), "");
Text(DataURLMime(StringView{nullptr, 0, true}), "");
Text(DataURLMime(Literal("http://a;b")), "//a");
auto wideData = Create16(u"data:TEXT/Plain;x", 17);
auto wideMime = DataURLMime(ViewOf(wideData));
Text(wideMime, "text/plain");
Check(!Is8Bit(wideMime));
auto accented = Create16(u"data:É/X,", 9);
Text(DataURLMime(ViewOf(accented)), "\xC3\x89/x");
auto widePlain = Create16(u"data:,x", 7);
Text(DataURLMime(ViewOf(widePlain)), "text/plain");
}
void TestURLsAndReallocation() {
struct PinnedBits {
unsigned valid : 1;
@@ -967,6 +1041,7 @@ void TestURLsAndReallocation() {
memory = static_cast<unsigned char*>(JSRealloc(memory, 2));
Check(memory[0] == 'h' && memory[1] == 'e');
Check(!JSRealloc(memory, 0));
TestURLStringHelpers();
}
} // namespace Wtf2Tests
+1 -3
View File
@@ -27,7 +27,7 @@
- The [revision-pinned identity inventory](https://gist.github.com/kyon-eth/d44995f181e1818977bd38f0e6fc0f34/8afcb14b0707a09b6274ff7f7bcf33ef46cfe2e7) records the module, library, symbol type and NIDs for the declarations in [Export.cpp](../../../core/libs/prx/libSceNKWebKit/Export.cpp); it is a metadata summary rather than independent verification. For the 255 absent from the public catalogue, [per-image ELF records](https://gist.github.com/kyon-eth/147be8dd556e9cced2577ccbed548972/1a659ecfe819e724675991a574a1aebb5fbb48e5) include the raw qualified names, module and library identities, symbol type, values and sizes; the record file SHA-256 is `44bdc4d6073192a8f41b7be359b75364b3d41dbbd11ce649924b8cebdd4ffe51`. Image labels are not authenticated.
- [Additional callable exports](../../../core/libs/prx/libSceNKWebKit/Export.cpp) - 7439 of the 8703 inventory declarations listed below throw through `NotImplemented_nid_no_patch`; signatures and behavior are unverified. The later 13.60-labelled image contains all 8703; 8448 match the public 3.20 catalogue, while 255 are absent and their presence in retail 3.20 is unverified. Per-image records show the latter in a separate 3.20-labelled image, but neither image label is authenticated. Identified names match NIDs in the [public symbol database](https://github.com/zecoxao/sce_symbols/blob/2883963a0a514ba6e77407a08ef4730a65e88254/aerolib.csv) or [supplemental catalog](https://github.com/claimore22/ps5rs/blob/2304be5131221bae0dac24b9767cabffda33f747/data/nids.csv). Data exports need separate analysis.
- [Additional callable exports](../../../core/libs/prx/libSceNKWebKit/Export.cpp) - 7437 of the 8703 inventory declarations listed below throw through `NotImplemented_nid_no_patch`; signatures and behavior are unverified. The later 13.60-labelled image contains all 8703; 8448 match the public 3.20 catalogue, while 255 are absent and their presence in retail 3.20 is unverified. Per-image records show the latter in a separate 3.20-labelled image, but neither image label is authenticated. Identified names match NIDs in the [public symbol database](https://github.com/zecoxao/sce_symbols/blob/2883963a0a514ba6e77407a08ef4730a65e88254/aerolib.csv) or [supplemental catalog](https://github.com/claimore22/ps5rs/blob/2304be5131221bae0dac24b9767cabffda33f747/data/nids.csv). Data exports need separate analysis.
| Name | NID |
| --- | --- |
@@ -1760,7 +1760,6 @@
| `_ZN3WTF19ParallelEnvironmentC1EPFvPvEmi` | `Efn-a1tGPqw` |
| `_ZN3WTF19ParallelEnvironmentC2EPFvPvEmi` | `ciXM3j2URKk` |
| `_ZN3WTF19isCompilationThreadEv` | `qoO6VaMuvG0` |
| `_ZN3WTF19mimeTypeFromDataURLENS_10StringViewE` | `kie+nv-1HCM` |
| `_ZN3WTF19numGraphemeClustersENS_10StringViewE` | `K7qAbz7P3rs` |
| `_ZN3WTF20ConcurrentPtrHashSet15deleteOldTablesEv` | `K59xDVxbCyM` |
| `_ZN3WTF20ConcurrentPtrHashSet5clearEv` | `sDuWnr1d9ko` |
@@ -6054,7 +6053,6 @@
| `_ZNK3WTF3URL19protocolHostAndPortEv` | `q8fEMeIqd5w` |
| `_ZNK3WTF3URL21truncatedForUseAsBaseEv` | `uekVJTVqBGc` |
| `_ZNK3WTF3URL24strippedForUseAsReferrerEv` | `CyN41AniueA` |
| `_ZNK3WTF3URL30stringCenterEllipsizedToLengthEj` | `JRPrmfTHt08` |
| `_ZNK3WTF3URL4dumpERNS_11PrintStreamE` | `ITwB6pPwmRc` |
| `_ZNK3WTF3URL4userEv` | `ETN4mn+-5l0` |
| `_ZNK3WTF3URL8passwordEv` | `aCtpeXWclTE` |