mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 12:24:24 +00:00
c0a9d571ce
Tool will try to extract useful information from invalid (e.g. partial or wrong version) dill. This is a first stab and could possibly be extended and improved in the future. Change-Id: Ib381794a3fe80036bb845800488fa0e1a7f04f83 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/211241 Commit-Queue: Jens Johansen <jensj@google.com> Reviewed-by: Johnni Winther <johnniwinther@google.com>
106 lines
3.5 KiB
Dart
Executable file
106 lines
3.5 KiB
Dart
Executable file
#!/usr/bin/env dart
|
|
// Copyright (c) 2021, 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.
|
|
|
|
import 'dart:io';
|
|
import 'dart:typed_data';
|
|
|
|
import 'package:kernel/kernel.dart'
|
|
show Component, Source, loadComponentFromBytes;
|
|
import 'package:kernel/binary/tag.dart' show Tag;
|
|
|
|
main(List<String> args) {
|
|
if (args.length != 1) {
|
|
throw "Usage: dart <script> <dillfile>";
|
|
}
|
|
File file = new File(args.single);
|
|
if (!file.existsSync()) {
|
|
throw "Given file doesn't exist.\n"
|
|
"Usage: dart <script> <dillfile>";
|
|
}
|
|
Uint8List bytes = file.readAsBytesSync();
|
|
List<Component> components = splitAndRead(bytes);
|
|
print("Sucessfully read ${components.length} sub-components.");
|
|
|
|
for (int i = 0; i < components.length; i++) {
|
|
Component component = components[i];
|
|
print("Component #${i + 1}:");
|
|
for (MapEntry<Uri, Source> entry in component.uriToSource.entries) {
|
|
String importUri = entry.value.importUri.toString();
|
|
String fileUri = entry.key.toString();
|
|
if (importUri != fileUri) {
|
|
print(" - $importUri ($fileUri)");
|
|
} else {
|
|
print(" - $fileUri");
|
|
}
|
|
}
|
|
}
|
|
|
|
// TODO(jensj): Could we read _some_ (useful) data from a partial component
|
|
// (e.g. one that stops after the first few libraries)?
|
|
}
|
|
|
|
List<Component> splitAndRead(Uint8List bytes) {
|
|
List<Component> components = [];
|
|
|
|
// Search for magic component file tag.
|
|
List<int> magicTagBytes = [
|
|
(Tag.ComponentFile >> 24) & 0XFF,
|
|
(Tag.ComponentFile >> 16) & 0XFF,
|
|
(Tag.ComponentFile >> 8) & 0XFF,
|
|
(Tag.ComponentFile >> 0) & 0XFF,
|
|
];
|
|
List<int> tagOffsets = [];
|
|
for (int index = 0; index < bytes.length - 7; index++) {
|
|
if (bytes[index] == magicTagBytes[0] &&
|
|
bytes[index + 1] == magicTagBytes[1] &&
|
|
bytes[index + 2] == magicTagBytes[2] &&
|
|
bytes[index + 3] == magicTagBytes[3]) {
|
|
// Try to read binary version too and see if it matches.
|
|
int version = (bytes[index + 4] << 24) |
|
|
(bytes[index + 5] << 16) |
|
|
(bytes[index + 6] << 8) |
|
|
bytes[index + 7];
|
|
if (version != Tag.BinaryFormatVersion) {
|
|
print("Found tag, but version mismatches "
|
|
"('$version' vs readable version '${Tag.BinaryFormatVersion}'). "
|
|
"Try again in a different checkout.");
|
|
} else {
|
|
tagOffsets.add(index);
|
|
}
|
|
}
|
|
}
|
|
print("Found ${tagOffsets.length} possible tag offsets.");
|
|
|
|
// Add fake file tag after end of bytes to also attempt "last component".
|
|
tagOffsets.add(bytes.length);
|
|
|
|
// Warning: O(n²) algorithm (though, as the tag is assumed to be rather unique
|
|
// in normal cases it will probably much better in practise
|
|
// (and n will be low)).
|
|
int fromIndex = 0;
|
|
while (fromIndex < tagOffsets.length - 1) {
|
|
int toIndex = fromIndex + 1;
|
|
while (toIndex < tagOffsets.length) {
|
|
// Cut bytes and try to load.
|
|
int fromOffset = tagOffsets[fromIndex];
|
|
int toOffset = tagOffsets[toIndex];
|
|
Uint8List bytesView =
|
|
new Uint8List.sublistView(bytes, fromOffset, toOffset);
|
|
try {
|
|
Component loaded = loadComponentFromBytes(bytesView);
|
|
components.add(loaded);
|
|
print("Loaded from tag ${fromIndex} to ${toIndex}.");
|
|
break;
|
|
} catch (e) {
|
|
print("Failed loading from tag ${fromIndex} to ${toIndex}"
|
|
" (${toOffset - fromOffset} bytes).");
|
|
toIndex++;
|
|
}
|
|
}
|
|
fromIndex++;
|
|
}
|
|
|
|
return components;
|
|
}
|