From: Jeff Halter Date: Tue, 24 May 2022 23:05:19 +0000 (-0700) Subject: Fix file corruption bug for commented files X-Git-Url: https://git.r.bdr.sh/rbdr/mobius/commitdiff_plain/bb7fe19f7e331f0e8c79f4da61543981acd36422 Fix file corruption bug for commented files This fixes a bug that happens when an uploaded file contains a file comment. The bug happens because the comment byte length was not included when calculating the length of the information header, causing the comment bytes to be appendedto the file. --- diff --git a/hotline/flattened_file_object.go b/hotline/flattened_file_object.go index 02804f6..ee8a69b 100644 --- a/hotline/flattened_file_object.go +++ b/hotline/flattened_file_object.go @@ -67,18 +67,18 @@ func NewFlatFileInformationFork(fileName string) FlatFileInformationFork { ModifyDate: []byte{0x07, 0x70, 0x00, 0x00, 0xba, 0x74, 0x24, 0x73}, // TODO: implement NameScript: make([]byte, 2), // TODO: What is this? Name: []byte(fileName), + CommentSize: []byte{0, 4}, Comment: []byte("TODO"), // TODO: implement (maybe?) } } -// Size of the flat file information fork, which is the fixed size of 72 bytes -// plus the number of bytes in the FileName -// TODO: plus the size of the Comment! +// DataSize calculates the size of the flat file information fork, which is +// 72 bytes for the fixed length fields plus the length of the Name + Comment func (ffif FlatFileInformationFork) DataSize() []byte { size := make([]byte, 4) - nameLen := len(ffif.Name) + //TODO: Can I do math directly on two byte slices? - dataSize := nameLen + 74 + dataSize := len(ffif.Name) + len(ffif.Comment) + 74 binary.BigEndian.PutUint32(size, uint32(dataSize)) @@ -184,9 +184,8 @@ func (f flattenedFileObject) BinaryMarshal() []byte { out = append(out, f.FlatFileInformationFork.NameScript...) out = append(out, f.FlatFileInformationFork.ReadNameSize()...) out = append(out, f.FlatFileInformationFork.Name...) - - // TODO: Implement commentlen and comment field - out = append(out, []byte{0, 0}...) + out = append(out, f.FlatFileInformationFork.CommentSize...) + out = append(out, f.FlatFileInformationFork.Comment...) out = append(out, f.FlatFileDataForkHeader.ForkType...) out = append(out, f.FlatFileDataForkHeader.CompressionType...) diff --git a/hotline/flattened_file_object_test.go b/hotline/flattened_file_object_test.go index df05c09..5bbaf1d 100644 --- a/hotline/flattened_file_object_test.go +++ b/hotline/flattened_file_object_test.go @@ -74,3 +74,67 @@ func TestNewFlattenedFileObject(t *testing.T) { }) } } + +func Test_flattenedFileObject_BinaryMarshal(t *testing.T) { + + testData, _ := hex.DecodeString("46494c500001000000000000000000000000000000000002494e464f000000000000000000000052414d414354455854747478740000000000000100000000000000000000000000000000000000000000000000000000000000000007700000ba74247307700000ba74247300000008746573742e74787400004441544100000000000000000000000474657374") + testFile := ReadFlattenedFileObject(testData) + testFile.FlatFileInformationFork.Comment = []byte("test!") + testFile.FlatFileInformationFork.CommentSize = []byte{0x00, 0x05} + + type fields struct { + FlatFileHeader FlatFileHeader + FlatFileInformationForkHeader FlatFileInformationForkHeader + FlatFileInformationFork FlatFileInformationFork + FlatFileDataForkHeader FlatFileDataForkHeader + FileData []byte + } + tests := []struct { + name string + fields fields + want []byte + }{ + { + name: "with a valid file", + fields: fields{ + FlatFileHeader: testFile.FlatFileHeader, + FlatFileInformationForkHeader: testFile.FlatFileInformationForkHeader, + FlatFileInformationFork: testFile.FlatFileInformationFork, + FlatFileDataForkHeader: testFile.FlatFileDataForkHeader, + FileData: testFile.FileData, + }, + want: []byte{ + 0x46, 0x49, 0x4c, 0x50, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x49, 0x4e, 0x46, 0x4f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, + 0x41, 0x4d, 0x41, 0x43, 0x54, 0x45, 0x58, 0x54, + 0x74, 0x74, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0x70, 0x00, 0x00, + 0xba, 0x74, 0x24, 0x73, 0x07, 0x70, 0x00, 0x00, + 0xba, 0x74, 0x24, 0x73, 0x00, 0x00, 0x00, 0x08, + 0x74, 0x65, 0x73, 0x74, 0x2e, 0x74, 0x78, 0x74, + 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x21, 0x44, + 0x41, 0x54, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + f := flattenedFileObject{ + FlatFileHeader: tt.fields.FlatFileHeader, + FlatFileInformationForkHeader: tt.fields.FlatFileInformationForkHeader, + FlatFileInformationFork: tt.fields.FlatFileInformationFork, + FlatFileDataForkHeader: tt.fields.FlatFileDataForkHeader, + FileData: tt.fields.FileData, + } + assert.Equalf(t, tt.want, f.BinaryMarshal(), "BinaryMarshal()") + }) + } +}