use of com.facebook.buck.io.FileContentsScrubber in project buck by facebook.
the class FileContentsScrubberOverflowTest method thatFileSizesOver32BitsIsOkay.
@Test
public void thatFileSizesOver32BitsIsOkay() throws IOException, FileScrubber.ScrubException {
FileContentsScrubber scrubber = ObjectFileScrubbers.createDateUidGidScrubber(ObjectFileScrubbers.PaddingStyle.LEFT);
scrubber.scrubFile(new FakeFileChannel());
}
use of com.facebook.buck.io.FileContentsScrubber in project buck by facebook.
the class ObjectFileScrubbers method createDateUidGidScrubber.
public static FileContentsScrubber createDateUidGidScrubber(final PaddingStyle paddingStyle) {
return new FileContentsScrubber() {
/**
* Efficiently modifies the archive backed by the given buffer to remove any non-deterministic
* meta-data such as timestamps, UIDs, and GIDs.
*/
@SuppressWarnings("PMD.AvoidUsingOctalValues")
@Override
public void scrubFile(FileChannel file) throws IOException, ScrubException {
try {
ByteBuffer header = ByteBuffer.allocate(GLOBAL_HEADER_SIZE);
file.read(header);
// Grab the global header chunk and verify it's accurate.
header.position(0);
byte[] globalHeader = getBytes(header, GLOBAL_HEADER_SIZE);
boolean thin = checkHeader(globalHeader);
// Iterate over all the file meta-data entries, injecting zero's for timestamp,
// UID, and GID.
final int entrySize = 16 + /* fileName */
12 + /* file modification time */
6 + /* owner ID */
6 + /* group ID */
8 + /* file mode */
10 + /* file size */
2;
long start = GLOBAL_HEADER_SIZE;
ByteBuffer buffer = ByteBuffer.allocate(entrySize);
while (start < file.size()) {
checkArchive(file.size() - start >= entrySize, "Invalid entry metadata format");
buffer.clear();
file.position(start);
int read = file.read(buffer);
checkArchive(read == entrySize, "Not all bytes have been read");
// position points just past the last byte read, so need to reset
buffer.position(0);
String fileName = new String(getBytes(buffer, 16), Charsets.US_ASCII).trim();
// Inject 0's for the non-deterministic meta-data entries.
/* File modification timestamp */
putIntAsDecimalString(buffer, 12, ObjectFileCommonModificationDate.COMMON_MODIFICATION_TIME_STAMP, paddingStyle);
/* Owner ID */
putIntAsDecimalString(buffer, 6, 0, paddingStyle);
/* Group ID */
putIntAsDecimalString(buffer, 6, 0, paddingStyle);
/* File mode */
putIntAsOctalString(buffer, 8, 0100644, paddingStyle);
long fileSize = getDecimalStringAsLong(buffer, 10);
// Lastly, grab the file magic entry and verify it's accurate.
byte[] fileMagic = getBytes(buffer, 2);
checkArchive(Arrays.equals(END_OF_FILE_HEADER_MARKER, fileMagic), "invalid file magic");
// write the changes
// position points just past the last byte accessed, need to reset
buffer.position(0);
file.position(start);
int written = file.write(buffer);
checkArchive(written == entrySize, "Not all bytes have been written");
// Skip the file data.
start += entrySize;
if (!thin || SPECIAL_ENTRIES.contains(fileName)) {
start += fileSize + fileSize % 2;
}
}
// Convert any low-level exceptions to `ArchiveExceptions`s.
} catch (BufferUnderflowException | ReadOnlyBufferException e) {
throw new ScrubException(e.getMessage());
}
}
};
}
Aggregations