2948f8c1b7
This moves Http code into dart:_http. dart:io then imports and re-exports dart:_http. This is the first stage of moving dart:_http into its own pub package. This CL was reverted due to a failure in the Flutter engine build which happened due to an incomplete change in gen_snapshot.cc, and to update sdk/lib/libraries.yaml and sdk/lib/libraries.json Change-Id: Ie90c77ef631aea7a163774b58e8ccbaf71a24d3c Reviewed-on: https://dart-review.googlesource.com/7588 Reviewed-by: Zach Anderson <zra@google.com>
217 lines
5.8 KiB
Dart
217 lines
5.8 KiB
Dart
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
// This test reflectively enumerates all the methods in the system and tries to
|
|
// invoke them with various basic values (nulls, ints, etc). This may result in
|
|
// Dart exceptions or hangs, but should never result in crashes or JavaScript
|
|
// exceptions.
|
|
|
|
library test.invoke_natives;
|
|
|
|
import 'dart:mirrors';
|
|
import 'dart:async';
|
|
|
|
// Methods to be skipped, by qualified name.
|
|
var blacklist = [
|
|
// Don't recurse on this test.
|
|
'test.invoke_natives',
|
|
|
|
// Don't exit the test pre-maturely.
|
|
'dart.io.exit',
|
|
|
|
// Don't change the exit code, which may fool the test harness.
|
|
'dart.io.exitCode',
|
|
|
|
// Don't kill random other processes.
|
|
'dart.io.Process.killPid',
|
|
|
|
// Don't break into the debugger.
|
|
'dart.developer.debugger',
|
|
|
|
// Don't run blocking io calls.
|
|
new RegExp(r".*Sync$"),
|
|
|
|
// These prevent the test from exiting.
|
|
'dart.io.sleep',
|
|
'dart._http.HttpServer.HttpServer.listenOn',
|
|
|
|
// These either cause the VM to segfault or throw uncatchable API errors.
|
|
// TODO(15274): Fix them and remove from blacklist.
|
|
'dart.io.SystemEncoding.decode', // Windows only
|
|
'dart.io.SystemEncoding.encode', // Windows only
|
|
|
|
// These construct an object with an uninitialized native field.
|
|
// TODO(23869): We could make this safer, but making the failure non-fatal
|
|
// would we worthless aside from this test.
|
|
'dart.io.X509Certificate.X509Certificate._',
|
|
'dart.io._X509Impl._X509Impl',
|
|
|
|
// Don't call private methods in dart.async as they may circumvent the zoned
|
|
// error handling below.
|
|
new RegExp(r"^dart\.async\._.*$"),
|
|
|
|
'dart._internal.fatal',
|
|
];
|
|
|
|
bool isBlacklisted(Symbol qualifiedSymbol) {
|
|
var qualifiedString = MirrorSystem.getName(qualifiedSymbol);
|
|
for (var pattern in blacklist) {
|
|
if (qualifiedString.contains(pattern)) {
|
|
print('Skipping $qualifiedString');
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
class Task {
|
|
var name;
|
|
var action;
|
|
}
|
|
|
|
var queue = new List();
|
|
|
|
checkMethod(MethodMirror m, ObjectMirror target, [origin]) {
|
|
if (isBlacklisted(m.qualifiedName)) return;
|
|
|
|
var task = new Task();
|
|
task.name = '${MirrorSystem.getName(m.qualifiedName)} from $origin';
|
|
|
|
if (m.isRegularMethod) {
|
|
task.action = () => target.invoke(
|
|
m.simpleName, new List.filled(m.parameters.length, fuzzArgument));
|
|
} else if (m.isGetter) {
|
|
task.action = () => target.getField(m.simpleName);
|
|
} else if (m.isSetter) {
|
|
task.action = () => target.setField(m.simpleName, null);
|
|
} else if (m.isConstructor) {
|
|
return;
|
|
} else {
|
|
throw "Unexpected method kind";
|
|
}
|
|
|
|
queue.add(task);
|
|
}
|
|
|
|
checkField(VariableMirror v, ObjectMirror target, [origin]) {
|
|
if (isBlacklisted(v.qualifiedName)) return;
|
|
|
|
var task = new Task();
|
|
task.name = '${MirrorSystem.getName(v.qualifiedName)} from $origin';
|
|
|
|
task.action = () => target.getField(v.simpleName);
|
|
|
|
queue.add(task);
|
|
}
|
|
|
|
checkInstance(instanceMirror, origin) {
|
|
ClassMirror klass = instanceMirror.type;
|
|
while (klass != null) {
|
|
instanceMirror.type.declarations.values
|
|
.where((d) => d is MethodMirror && !d.isStatic)
|
|
.forEach((m) => checkMethod(m, instanceMirror, origin));
|
|
instanceMirror.type.declarations.values
|
|
.where((d) => d is VariableMirror)
|
|
.forEach((v) => checkField(v, instanceMirror, origin));
|
|
klass = klass.superclass;
|
|
}
|
|
}
|
|
|
|
checkClass(classMirror) {
|
|
classMirror.declarations.values
|
|
.where((d) => d is MethodMirror && d.isStatic)
|
|
.forEach((m) => checkMethod(m, classMirror));
|
|
|
|
classMirror.declarations.values
|
|
.where((d) => d is MethodMirror && d.isConstructor)
|
|
.forEach((m) {
|
|
if (isBlacklisted(m.qualifiedName)) return;
|
|
var task = new Task();
|
|
task.name = MirrorSystem.getName(m.qualifiedName);
|
|
|
|
task.action = () {
|
|
var instance = classMirror.newInstance(m.constructorName,
|
|
new List.filled(m.parameters.length, fuzzArgument));
|
|
checkInstance(instance, task.name);
|
|
};
|
|
queue.add(task);
|
|
});
|
|
}
|
|
|
|
checkLibrary(libraryMirror) {
|
|
print(libraryMirror.simpleName);
|
|
if (isBlacklisted(libraryMirror.qualifiedName)) return;
|
|
|
|
libraryMirror.declarations.values
|
|
.where((d) => d is ClassMirror)
|
|
.forEach(checkClass);
|
|
|
|
libraryMirror.declarations.values
|
|
.where((d) => d is MethodMirror)
|
|
.forEach((m) => checkMethod(m, libraryMirror));
|
|
}
|
|
|
|
var testZone;
|
|
|
|
doOneTask() {
|
|
if (queue.length == 0) {
|
|
print('Done');
|
|
return;
|
|
}
|
|
|
|
var task = queue.removeLast();
|
|
print(task.name);
|
|
try {
|
|
task.action();
|
|
} catch (e) {}
|
|
|
|
// Register the next task in a timer callback so as to yield to async code
|
|
// scheduled in the current task. This isn't necessary for the test itself,
|
|
// but is helpful when trying to figure out which function is responsible for
|
|
// a crash.
|
|
testZone.createTimer(Duration.ZERO, doOneTask);
|
|
}
|
|
|
|
var fuzzArgument;
|
|
|
|
main() {
|
|
fuzzArgument = null;
|
|
fuzzArgument = 1; // //# smi: ok
|
|
fuzzArgument = false; // //# false: ok
|
|
fuzzArgument = 'string'; // //# string: ok
|
|
fuzzArgument = new List(0); // //# emptyarray: ok
|
|
|
|
print('Fuzzing with $fuzzArgument');
|
|
|
|
currentMirrorSystem().libraries.values.forEach(checkLibrary);
|
|
|
|
var valueObjects = [
|
|
true,
|
|
false,
|
|
null,
|
|
[],
|
|
{},
|
|
dynamic,
|
|
0,
|
|
0xEFFFFFF,
|
|
0xFFFFFFFF,
|
|
0xFFFFFFFFFFFFFFFF,
|
|
3.14159,
|
|
() {},
|
|
"foo",
|
|
'blåbærgrød',
|
|
'Îñţérñåţîöñåļîžåţîờñ',
|
|
"\u{1D11E}",
|
|
#symbol
|
|
];
|
|
valueObjects.forEach((v) => checkInstance(reflect(v), 'value object'));
|
|
|
|
void uncaughtErrorHandler(self, parent, zone, error, stack) {}
|
|
|
|
var zoneSpec =
|
|
new ZoneSpecification(handleUncaughtError: uncaughtErrorHandler);
|
|
testZone = Zone.current.fork(specification: zoneSpec);
|
|
testZone.createTimer(Duration.ZERO, doOneTask);
|
|
}
|