Skip to content

Commit 91d4601

Browse files
mkustermanncommit-bot@chromium.org
authored andcommitted
[vm/service] Avoid exposing top-level class ids in the service protocol
Instead of using class ids when building field/function service ids, we use names instead (as we do in some other places already). Issue #42533 Change-Id: I55530161af26ee9514aa29a048cf140094cabd95 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/156004 Commit-Queue: Martin Kustermann <[email protected]> Reviewed-by: Ryan Macnak <[email protected]> Reviewed-by: Ben Konyi <[email protected]>
1 parent 101ad65 commit 91d4601

File tree

2 files changed

+133
-79
lines changed

2 files changed

+133
-79
lines changed

runtime/vm/object_service.cc

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -247,16 +247,30 @@ static void AddFunctionServiceId(const JSONObject& jsobj,
247247
}
248248
if (id != -1) {
249249
ASSERT(selector != NULL);
250-
jsobj.AddFixedServiceId("classes/%" Pd "/%s/%" Pd "", cls.id(), selector,
251-
id);
250+
if (cls.IsTopLevel()) {
251+
const auto& library = Library::Handle(cls.library());
252+
const auto& private_key = String::Handle(library.private_key());
253+
jsobj.AddFixedServiceId("libraries/%s/%s/%" Pd "",
254+
private_key.ToCString(), selector, id);
255+
} else {
256+
jsobj.AddFixedServiceId("classes/%" Pd "/%s/%" Pd "", cls.id(), selector,
257+
id);
258+
}
252259
return;
253260
}
254261
// Regular functions known to their owner use their name (percent-encoded).
255262
String& name = String::Handle(f.name());
256263
if (cls.LookupFunction(name) == f.raw()) {
257264
const char* encoded_name = String::EncodeIRI(name);
258-
jsobj.AddFixedServiceId("classes/%" Pd "/functions/%s", cls.id(),
259-
encoded_name);
265+
if (cls.IsTopLevel()) {
266+
const auto& library = Library::Handle(cls.library());
267+
const auto& private_key = String::Handle(library.private_key());
268+
jsobj.AddFixedServiceId("libraries/%s/functions/%s",
269+
private_key.ToCString(), encoded_name);
270+
} else {
271+
jsobj.AddFixedServiceId("classes/%" Pd "/functions/%s", cls.id(),
272+
encoded_name);
273+
}
260274
return;
261275
}
262276
// Oddball functions (not known to their owner) fall back to use the object
@@ -356,8 +370,15 @@ void Field::PrintJSONImpl(JSONStream* stream, bool ref) const {
356370
String& field_name = String::Handle(name());
357371
const char* encoded_field_name = String::EncodeIRI(field_name);
358372
AddCommonObjectProperties(&jsobj, "Field", ref);
359-
jsobj.AddFixedServiceId("classes/%" Pd "/fields/%s", cls.id(),
360-
encoded_field_name);
373+
if (cls.IsTopLevel()) {
374+
const auto& library = Library::Handle(cls.library());
375+
const auto& private_key = String::Handle(library.private_key());
376+
jsobj.AddFixedServiceId("libraries/%s/fields/%s", private_key.ToCString(),
377+
encoded_field_name);
378+
} else {
379+
jsobj.AddFixedServiceId("classes/%" Pd "/fields/%s", cls.id(),
380+
encoded_field_name);
381+
}
361382

362383
const char* user_name = UserVisibleNameCString();
363384
const String& vm_name = String::Handle(name());

runtime/vm/service.cc

Lines changed: 106 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1697,6 +1697,84 @@ static ObjectPtr LookupObjectId(Thread* thread,
16971697
return ring->GetObjectForId(id, kind);
16981698
}
16991699

1700+
static ObjectPtr LookupClassMembers(Thread* thread,
1701+
const Class& klass,
1702+
char** parts,
1703+
int num_parts) {
1704+
auto isolate = thread->isolate();
1705+
auto zone = thread->zone();
1706+
1707+
if (num_parts != 4) {
1708+
return Object::sentinel().raw();
1709+
}
1710+
1711+
const char* encoded_id = parts[3];
1712+
auto& id = String::Handle(String::New(encoded_id));
1713+
id = String::DecodeIRI(id);
1714+
if (id.IsNull()) {
1715+
return Object::sentinel().raw();
1716+
}
1717+
1718+
if (strcmp(parts[2], "fields") == 0) {
1719+
// Field ids look like: "classes/17/fields/name"
1720+
const auto& field = Field::Handle(klass.LookupField(id));
1721+
if (field.IsNull()) {
1722+
return Object::sentinel().raw();
1723+
}
1724+
return field.raw();
1725+
}
1726+
if (strcmp(parts[2], "functions") == 0) {
1727+
// Function ids look like: "classes/17/functions/name"
1728+
const auto& function = Function::Handle(klass.LookupFunction(id));
1729+
if (function.IsNull()) {
1730+
return Object::sentinel().raw();
1731+
}
1732+
return function.raw();
1733+
}
1734+
if (strcmp(parts[2], "implicit_closures") == 0) {
1735+
// Function ids look like: "classes/17/implicit_closures/11"
1736+
intptr_t id;
1737+
if (!GetIntegerId(parts[3], &id)) {
1738+
return Object::sentinel().raw();
1739+
}
1740+
const auto& func =
1741+
Function::Handle(zone, klass.ImplicitClosureFunctionFromIndex(id));
1742+
if (func.IsNull()) {
1743+
return Object::sentinel().raw();
1744+
}
1745+
return func.raw();
1746+
}
1747+
if (strcmp(parts[2], "dispatchers") == 0) {
1748+
// Dispatcher Function ids look like: "classes/17/dispatchers/11"
1749+
intptr_t id;
1750+
if (!GetIntegerId(parts[3], &id)) {
1751+
return Object::sentinel().raw();
1752+
}
1753+
const auto& func =
1754+
Function::Handle(zone, klass.InvocationDispatcherFunctionFromIndex(id));
1755+
if (func.IsNull()) {
1756+
return Object::sentinel().raw();
1757+
}
1758+
return func.raw();
1759+
}
1760+
if (strcmp(parts[2], "closures") == 0) {
1761+
// Closure ids look like: "classes/17/closures/11"
1762+
intptr_t id;
1763+
if (!GetIntegerId(parts[3], &id)) {
1764+
return Object::sentinel().raw();
1765+
}
1766+
Function& func = Function::Handle(zone);
1767+
func = isolate->ClosureFunctionFromIndex(id);
1768+
if (func.IsNull()) {
1769+
return Object::sentinel().raw();
1770+
}
1771+
return func.raw();
1772+
}
1773+
1774+
UNREACHABLE();
1775+
return Object::sentinel().raw();
1776+
}
1777+
17001778
static ObjectPtr LookupHeapObjectLibraries(Isolate* isolate,
17011779
char** parts,
17021780
int num_parts) {
@@ -1724,9 +1802,30 @@ static ObjectPtr LookupHeapObjectLibraries(Isolate* isolate,
17241802
if (!lib_found) {
17251803
return Object::sentinel().raw();
17261804
}
1805+
1806+
const auto& klass = Class::Handle(lib.toplevel_class());
1807+
ASSERT(!klass.IsNull());
1808+
17271809
if (num_parts == 2) {
17281810
return lib.raw();
17291811
}
1812+
if (strcmp(parts[2], "fields") == 0) {
1813+
// Library field ids look like: "libraries/17/fields/name"
1814+
return LookupClassMembers(Thread::Current(), klass, parts, num_parts);
1815+
}
1816+
if (strcmp(parts[2], "functions") == 0) {
1817+
// Library function ids look like: "libraries/17/functions/name"
1818+
return LookupClassMembers(Thread::Current(), klass, parts, num_parts);
1819+
}
1820+
if (strcmp(parts[2], "closures") == 0) {
1821+
// Library function ids look like: "libraries/17/closures/name"
1822+
return LookupClassMembers(Thread::Current(), klass, parts, num_parts);
1823+
}
1824+
if (strcmp(parts[2], "implicit_closures") == 0) {
1825+
// Library function ids look like: "libraries/17/implicit_closures/name"
1826+
return LookupClassMembers(Thread::Current(), klass, parts, num_parts);
1827+
}
1828+
17301829
if (strcmp(parts[2], "scripts") == 0) {
17311830
// Script ids look like "libraries/35/scripts/library%2Furl.dart/12345"
17321831
if (num_parts != 5) {
@@ -1783,86 +1882,19 @@ static ObjectPtr LookupHeapObjectClasses(Thread* thread,
17831882
}
17841883
if (strcmp(parts[2], "closures") == 0) {
17851884
// Closure ids look like: "classes/17/closures/11"
1786-
if (num_parts != 4) {
1787-
return Object::sentinel().raw();
1788-
}
1789-
intptr_t id;
1790-
if (!GetIntegerId(parts[3], &id)) {
1791-
return Object::sentinel().raw();
1792-
}
1793-
Function& func = Function::Handle(zone);
1794-
func = isolate->ClosureFunctionFromIndex(id);
1795-
if (func.IsNull()) {
1796-
return Object::sentinel().raw();
1797-
}
1798-
return func.raw();
1799-
1885+
return LookupClassMembers(thread, cls, parts, num_parts);
18001886
} else if (strcmp(parts[2], "fields") == 0) {
18011887
// Field ids look like: "classes/17/fields/name"
1802-
if (num_parts != 4) {
1803-
return Object::sentinel().raw();
1804-
}
1805-
const char* encoded_id = parts[3];
1806-
String& id = String::Handle(zone, String::New(encoded_id));
1807-
id = String::DecodeIRI(id);
1808-
if (id.IsNull()) {
1809-
return Object::sentinel().raw();
1810-
}
1811-
Field& field = Field::Handle(zone, cls.LookupField(id));
1812-
if (field.IsNull()) {
1813-
return Object::sentinel().raw();
1814-
}
1815-
return field.raw();
1816-
1888+
return LookupClassMembers(thread, cls, parts, num_parts);
18171889
} else if (strcmp(parts[2], "functions") == 0) {
18181890
// Function ids look like: "classes/17/functions/name"
1819-
if (num_parts != 4) {
1820-
return Object::sentinel().raw();
1821-
}
1822-
const char* encoded_id = parts[3];
1823-
String& id = String::Handle(zone, String::New(encoded_id));
1824-
id = String::DecodeIRI(id);
1825-
if (id.IsNull()) {
1826-
return Object::sentinel().raw();
1827-
}
1828-
Function& func = Function::Handle(zone, cls.LookupFunction(id));
1829-
if (func.IsNull()) {
1830-
return Object::sentinel().raw();
1831-
}
1832-
return func.raw();
1833-
1891+
return LookupClassMembers(thread, cls, parts, num_parts);
18341892
} else if (strcmp(parts[2], "implicit_closures") == 0) {
18351893
// Function ids look like: "classes/17/implicit_closures/11"
1836-
if (num_parts != 4) {
1837-
return Object::sentinel().raw();
1838-
}
1839-
intptr_t id;
1840-
if (!GetIntegerId(parts[3], &id)) {
1841-
return Object::sentinel().raw();
1842-
}
1843-
Function& func = Function::Handle(zone);
1844-
func = cls.ImplicitClosureFunctionFromIndex(id);
1845-
if (func.IsNull()) {
1846-
return Object::sentinel().raw();
1847-
}
1848-
return func.raw();
1849-
1894+
return LookupClassMembers(thread, cls, parts, num_parts);
18501895
} else if (strcmp(parts[2], "dispatchers") == 0) {
18511896
// Dispatcher Function ids look like: "classes/17/dispatchers/11"
1852-
if (num_parts != 4) {
1853-
return Object::sentinel().raw();
1854-
}
1855-
intptr_t id;
1856-
if (!GetIntegerId(parts[3], &id)) {
1857-
return Object::sentinel().raw();
1858-
}
1859-
Function& func = Function::Handle(zone);
1860-
func = cls.InvocationDispatcherFunctionFromIndex(id);
1861-
if (func.IsNull()) {
1862-
return Object::sentinel().raw();
1863-
}
1864-
return func.raw();
1865-
1897+
return LookupClassMembers(thread, cls, parts, num_parts);
18661898
} else if (strcmp(parts[2], "types") == 0) {
18671899
// Type ids look like: "classes/17/types/11"
18681900
if (num_parts != 4) {
@@ -2707,7 +2739,8 @@ static bool BuildExpressionEvaluationScope(Thread* thread, JSONStream* js) {
27072739
cls = instance.clazz();
27082740
isStatic = false;
27092741
}
2710-
if (cls.id() < kInstanceCid || cls.id() == kTypeArgumentsCid) {
2742+
if (!cls.IsTopLevel() &&
2743+
(cls.id() < kInstanceCid || cls.id() == kTypeArgumentsCid)) {
27112744
js->PrintError(
27122745
kInvalidParams,
27132746
"Expressions can be evaluated only with regular Dart instances");

0 commit comments

Comments
 (0)