|
Packit Service |
2a3f3d |
#!/usr/bin/env gjs
|
|
Packit Service |
2a3f3d |
//
|
|
Packit Service |
2a3f3d |
// Copyright (C) 2014 Colin Walters <walters@verbum.org>
|
|
Packit Service |
2a3f3d |
//
|
|
Packit Service |
2a3f3d |
// SPDX-License-Identifier: LGPL-2.0+
|
|
Packit Service |
2a3f3d |
//
|
|
Packit Service |
2a3f3d |
// This library is free software; you can redistribute it and/or
|
|
Packit Service |
2a3f3d |
// modify it under the terms of the GNU Lesser General Public
|
|
Packit Service |
2a3f3d |
// License as published by the Free Software Foundation; either
|
|
Packit Service |
2a3f3d |
// version 2 of the License, or (at your option) any later version.
|
|
Packit Service |
2a3f3d |
//
|
|
Packit Service |
2a3f3d |
// This library is distributed in the hope that it will be useful,
|
|
Packit Service |
2a3f3d |
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
2a3f3d |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit Service |
2a3f3d |
// Lesser General Public License for more details.
|
|
Packit Service |
2a3f3d |
//
|
|
Packit Service |
2a3f3d |
// You should have received a copy of the GNU Lesser General Public
|
|
Packit Service |
2a3f3d |
// License along with this library; if not, write to the
|
|
Packit Service |
2a3f3d |
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
Packit Service |
2a3f3d |
// Boston, MA 02111-1307, USA.
|
|
Packit Service |
2a3f3d |
|
|
Packit Service |
2a3f3d |
const GLib = imports.gi.GLib;
|
|
Packit Service |
2a3f3d |
const Gio = imports.gi.Gio;
|
|
Packit Service |
2a3f3d |
const OSTree = imports.gi.OSTree;
|
|
Packit Service |
2a3f3d |
|
|
Packit Service |
2a3f3d |
let repoPathArg = ARGV[0];
|
|
Packit Service |
2a3f3d |
let refToCorrupt = ARGV[1];
|
|
Packit Service |
2a3f3d |
|
|
Packit Service |
2a3f3d |
let repo = OSTree.Repo.new(Gio.File.new_for_path(repoPathArg));
|
|
Packit Service |
2a3f3d |
|
|
Packit Service |
2a3f3d |
repo.open(null);
|
|
Packit Service |
2a3f3d |
|
|
Packit Service |
2a3f3d |
function listObjectChecksumsRecurse(dir, allObjects) {
|
|
Packit Service |
2a3f3d |
dir.ensure_resolved();
|
|
Packit Service |
2a3f3d |
allObjects[dir.tree_get_contents_checksum() + '.dirtree'] = true;
|
|
Packit Service |
2a3f3d |
allObjects[dir.get_checksum() + '.dirmeta'] = true;
|
|
Packit Service |
2a3f3d |
let e = dir.enumerate_children('standard::name,standard::type', 0, null);
|
|
Packit Service |
2a3f3d |
let info;
|
|
Packit Service |
2a3f3d |
while ((info = e.next_file(null)) != null) {
|
|
Packit Service |
2a3f3d |
let child = e.get_child(info);
|
|
Packit Service |
2a3f3d |
child.ensure_resolved();
|
|
Packit Service |
2a3f3d |
print(info.get_name() + " is " + info.get_file_type());
|
|
Packit Service |
2a3f3d |
if (info.get_file_type() == Gio.FileType.DIRECTORY) {
|
|
Packit Service |
2a3f3d |
listObjectChecksumsRecurse(child, allObjects);
|
|
Packit Service |
2a3f3d |
} else {
|
|
Packit Service |
2a3f3d |
allObjects[child.get_checksum() + '.filez'] = true;
|
|
Packit Service |
2a3f3d |
}
|
|
Packit Service |
2a3f3d |
}
|
|
Packit Service |
2a3f3d |
e.close(null);
|
|
Packit Service |
2a3f3d |
}
|
|
Packit Service |
2a3f3d |
|
|
Packit Service |
2a3f3d |
let [,root,commit] = repo.read_commit(refToCorrupt, null);
|
|
Packit Service |
2a3f3d |
let allObjects = {};
|
|
Packit Service |
2a3f3d |
allObjects[commit + '.commit'] = true;
|
|
Packit Service |
2a3f3d |
listObjectChecksumsRecurse(root, allObjects);
|
|
Packit Service |
2a3f3d |
let i = 0;
|
|
Packit Service |
2a3f3d |
for (let v in allObjects)
|
|
Packit Service |
2a3f3d |
i++;
|
|
Packit Service |
2a3f3d |
print("commit " + commit + " refers to " + i + " objects");
|
|
Packit Service |
2a3f3d |
let offset = GLib.random_int_range(0, i);
|
|
Packit Service |
2a3f3d |
let objectToCorrupt = null;
|
|
Packit Service |
2a3f3d |
for (let v in allObjects) {
|
|
Packit Service |
2a3f3d |
if (offset <= 0) {
|
|
Packit Service |
2a3f3d |
objectToCorrupt = v;
|
|
Packit Service |
2a3f3d |
break;
|
|
Packit Service |
2a3f3d |
}
|
|
Packit Service |
2a3f3d |
offset--;
|
|
Packit Service |
2a3f3d |
}
|
|
Packit Service |
2a3f3d |
print("Choosing " + objectToCorrupt + " to corrupt");
|
|
Packit Service |
2a3f3d |
|
|
Packit Service |
2a3f3d |
let loosePath = repo.get_path().resolve_relative_path('objects/' + objectToCorrupt.substring(0, 2) + "/" + objectToCorrupt.substring(2));
|
|
Packit Service |
2a3f3d |
|
|
Packit Service |
2a3f3d |
let iostream = loosePath.open_readwrite(null);
|
|
Packit Service |
2a3f3d |
let info = iostream.query_info('standard::size', null);
|
|
Packit Service |
2a3f3d |
let size = info.get_size();
|
|
Packit Service |
2a3f3d |
let datain = Gio.DataInputStream.new(iostream.get_input_stream());
|
|
Packit Service |
2a3f3d |
let dataout = Gio.DataOutputStream.new(iostream.get_output_stream());
|
|
Packit Service |
2a3f3d |
let bytesToChange = 10;
|
|
Packit Service |
2a3f3d |
let status = "";
|
|
Packit Service |
2a3f3d |
var bytesChanged = {}
|
|
Packit Service |
2a3f3d |
for (i = 0; i < bytesToChange; i++) {
|
|
Packit Service |
2a3f3d |
let byteOffsetToCorrupt;
|
|
Packit Service |
2a3f3d |
do {
|
|
Packit Service |
2a3f3d |
byteOffsetToCorrupt = GLib.random_int_range(0, size);
|
|
Packit Service |
2a3f3d |
} while (byteOffsetToCorrupt in bytesChanged);
|
|
Packit Service |
2a3f3d |
iostream.seek(byteOffsetToCorrupt, GLib.SeekType.SET, null);
|
|
Packit Service |
2a3f3d |
let inbyte = datain.read_byte(null);
|
|
Packit Service |
2a3f3d |
let outbyte = (inbyte + 1) % 255;
|
|
Packit Service |
2a3f3d |
dataout.put_byte(outbyte, null);
|
|
Packit Service |
2a3f3d |
bytesChanged[byteOffsetToCorrupt] = byteOffsetToCorrupt;
|
|
Packit Service |
2a3f3d |
status += "Changed byte offset " + byteOffsetToCorrupt + " from " + inbyte + " to " + outbyte + "\n";
|
|
Packit Service |
2a3f3d |
}
|
|
Packit Service |
2a3f3d |
dataout.flush(null);
|
|
Packit Service |
2a3f3d |
iostream.close(null);
|
|
Packit Service |
2a3f3d |
|
|
Packit Service |
2a3f3d |
print(status);
|
|
Packit Service |
2a3f3d |
let successFile = Gio.File.new_for_path('corrupted-status.txt');
|
|
Packit Service |
2a3f3d |
successFile.replace_contents(status, null, false, 0, null);
|