public void CheckInvalidBSDFileEntry() { // Input invalid BSD Length { var stream = new MemoryStream(); stream.Write(ArArchiveFile.Magic); var entry = new Span <byte>(new byte[ArFile.FileEntrySizeInBytes]); entry.Fill((byte)' '); entry[0] = (byte)'#'; entry[1] = (byte)'1'; entry[2] = (byte)'/'; entry[3] = (byte)'a'; stream.Write(entry); stream.Position = 0; Assert.False(ArArchiveFile.TryRead(stream, ArArchiveKind.BSD, out _, out var diagnostics)); ExpectDiagnostics(diagnostics, DiagnosticId.AR_ERR_InvalidCharacterFoundInFileEntry); } // Input invalid BSD Length { var stream = new MemoryStream(); stream.Write(ArArchiveFile.Magic); var entry = new Span <byte>(new byte[ArFile.FileEntrySizeInBytes]); entry.Fill((byte)' '); entry[0] = (byte)'#'; entry[1] = (byte)'1'; entry[2] = (byte)'/'; entry[3] = (byte)'2'; // it will try to read 2 bytes for the name but won't find it entry[ArFile.FieldEndCharactersOffset] = (byte)'`'; entry[ArFile.FieldEndCharactersOffset + 1] = (byte)'\n'; stream.Write(entry); var continuePosition = stream.Position; stream.Position = 0; Assert.False(ArArchiveFile.TryRead(stream, ArArchiveKind.BSD, out _, out var diagnostics)); ExpectDiagnostics(diagnostics, DiagnosticId.AR_ERR_UnexpectedEndOfFile); // Check validity of BSD name stream.Position = continuePosition; stream.WriteByte((byte)'a'); stream.WriteByte((byte)'b'); stream.Position = 0; var result = ArArchiveFile.TryRead(stream, ArArchiveKind.BSD, out var arFile, out diagnostics); Assert.True(result, $"Error while reading file: {diagnostics}"); Assert.AreEqual(1, arFile.Files.Count, "Invalid number of file entries found"); Assert.AreEqual("ab", arFile.Files[0].Name, "Invalid name of file entry[0] found"); Assert.Null(arFile.SymbolTable, "Invalid non-null symbol table found"); } }
public void CheckInvalidFileEntry() { // Incorrect entry length { var stream = new MemoryStream(); stream.Write(ArArchiveFile.Magic); stream.Write(new byte[] { (byte)'a', (byte)'b' }); stream.Position = 0; Assert.False(ArArchiveFile.TryRead(stream, ArArchiveKind.GNU, out _, out var diagnostics)); ExpectDiagnostics(diagnostics, DiagnosticId.AR_ERR_InvalidFileEntryLength); } // Input invalid non-numeric characters into decimal/octal fields in file entry { var offsets = new int[] { ArFile.FieldTimestampOffset, ArFile.FieldOwnerIdOffset, ArFile.FieldGroupIdOffset, ArFile.FieldFileModeOffset, ArFile.FieldFileSizeOffset, ArFile.FieldEndCharactersOffset }; foreach (var offset in offsets) { var stream = new MemoryStream(); stream.Write(ArArchiveFile.Magic); var entry = new Span <byte>(new byte[ArFile.FileEntrySizeInBytes]); entry.Fill((byte)' '); entry[offset] = (byte)'a'; stream.Write(entry); stream.Position = 0; Assert.False(ArArchiveFile.TryRead(stream, ArArchiveKind.GNU, out _, out var diagnostics)); ExpectDiagnostics(diagnostics, DiagnosticId.AR_ERR_InvalidCharacterFoundInFileEntry); } } // Input name with `/` { var stream = new MemoryStream(); stream.Write(ArArchiveFile.Magic); var entry = new Span <byte>(new byte[ArFile.FileEntrySizeInBytes]); entry.Fill((byte)' '); entry[0] = (byte)'a'; entry[1] = (byte)'b'; entry[2] = (byte)'/'; entry[3] = (byte)'c'; entry[ArFile.FieldEndCharactersOffset] = (byte)'`'; entry[ArFile.FieldEndCharactersOffset + 1] = (byte)'\n'; stream.Write(entry); stream.Position = 0; Assert.False(ArArchiveFile.TryRead(stream, ArArchiveKind.GNU, out _, out var diagnostics)); ExpectDiagnostics(diagnostics, DiagnosticId.AR_ERR_InvalidCharacterInFileEntryName); } // Input length of content { var stream = new MemoryStream(); stream.Write(ArArchiveFile.Magic); var entry = new Span <byte>(new byte[ArFile.FileEntrySizeInBytes]); entry.Fill((byte)' '); entry[0] = (byte)'a'; entry[ArFile.FieldFileSizeOffset] = (byte)'2'; entry[ArFile.FieldEndCharactersOffset] = (byte)'`'; entry[ArFile.FieldEndCharactersOffset + 1] = (byte)'\n'; stream.Write(entry); var continuePosition = stream.Position; stream.Position = 0; Assert.False(ArArchiveFile.TryRead(stream, ArArchiveKind.GNU, out _, out var diagnostics)); ExpectDiagnostics(diagnostics, DiagnosticId.AR_ERR_UnexpectedEndOfFile); stream.Position = continuePosition; stream.WriteByte(0); stream.WriteByte(1); stream.Position = 0; // Check that we can actually read the content var result = ArArchiveFile.TryRead(stream, ArArchiveKind.GNU, out var arFile, out diagnostics); ExpectNoDiagnostics(diagnostics); Assert.True(result, $"Error while reading file: {diagnostics}"); Assert.AreEqual(1, arFile.Files.Count, "Invalid number of file entries found"); Assert.AreEqual("a", arFile.Files[0].Name, "Invalid name of file entry[0] found"); Assert.AreEqual(2, arFile.Files[0].Size, "Invalid size of file entry[0] found"); Assert.IsInstanceOf <ArBinaryFile>(arFile.Files[0], "Invalid instance of of file entry[0] "); var fileStream = ((ArBinaryFile)arFile.Files[0]).Stream; var read = new byte[] { (byte)fileStream.ReadByte(), (byte)fileStream.ReadByte() }; Assert.AreEqual(new byte[] { 0, 1 }, read, "Invalid content of of file entry[0] "); Assert.Null(arFile.SymbolTable, "Invalid non-null symbol table found"); } // Input length of content { var stream = new MemoryStream(); stream.Write(ArArchiveFile.Magic); var entry = new Span <byte>(new byte[ArFile.FileEntrySizeInBytes]); entry.Fill((byte)' '); entry[0] = (byte)'a'; entry[ArFile.FieldFileSizeOffset] = (byte)'1'; entry[ArFile.FieldEndCharactersOffset] = (byte)'`'; entry[ArFile.FieldEndCharactersOffset + 1] = (byte)'\n'; stream.Write(entry); stream.WriteByte(0); var continuePosition = stream.Position; stream.Position = 0; Assert.False(ArArchiveFile.TryRead(stream, ArArchiveKind.GNU, out _, out var diagnostics)); ExpectDiagnostics(diagnostics, DiagnosticId.AR_ERR_UnexpectedEndOfFile); stream.Position = continuePosition; stream.WriteByte(0); stream.Position = 0; Assert.False(ArArchiveFile.TryRead(stream, ArArchiveKind.GNU, out _, out diagnostics)); ExpectDiagnostics(diagnostics, DiagnosticId.AR_ERR_ExpectingNewLineCharacter); stream.Position = continuePosition; stream.WriteByte((byte)'\n'); stream.Position = 0; Assert.True(ArArchiveFile.TryRead(stream, ArArchiveKind.GNU, out _, out diagnostics)); ExpectNoDiagnostics(diagnostics); } }