Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 94 additions & 0 deletions 03-fuzz/bogacheva/fuzzer/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package main

import (
"encoding/binary"
"fmt"
"log"
"math/rand"
"os"
"os/exec"
)

type Project struct {
Repo [59]byte
Mark uint8
}

type Student struct {
Name [32]byte
Login [16]byte
Group [8]byte
Practice [8]uint8
Project
Mark float32
}

func generateRandomBytes(n int) []byte {
b := make([]byte, n)
rand.Read(b)
return b
}

func fuzzTest() {
log.Printf("Start fuzzing")
fileName := "test.bin"
file, err := os.Create(fileName)
if err != nil {
panic(err)
}
defer file.Close()
defer os.Remove(fileName)

var students [1000]Student
for i := range students {
copy(students[i].Name[:], generateRandomBytes(32))
copy(students[i].Login[:], generateRandomBytes(16))
copy(students[i].Group[:], generateRandomBytes(8))
for j := range students[i].Practice {
students[i].Practice[j] = uint8(rand.Intn(256))
}
copy(students[i].Repo[:], generateRandomBytes(59))
students[i].Mark = float32(rand.Float64())

err = binary.Write(file, binary.LittleEndian, &students[i])
if err != nil {
panic(err)
}
}

cmd := exec.Command("go", "run", "../sstable-panesh-bogacheva.go.go", fileName)
cmd.Stderr = os.Stderr
if err = cmd.Start(); err != nil {
log.Fatal("Failed to start fuzzer: ", err)
}

err = cmd.Wait()
if exitError, ok := err.(*exec.ExitError); ok {
code := exitError.ExitCode()
if code != 1 {
fmt.Println("Fuzzing test failed: Binary expected to reject malformed input, but it did not.")
fmt.Println(code)
} else {
fmt.Println("Fuzzing test passed: Binary correctly rejected malformed input.")
}
return
}

if err != nil {
log.Fatal("Fuzzer crashed: ", err)
}

fmt.Println("Fuzzing test passed: Binary correctly handled malformed input.")
}

func main() {
for i := 0; i < 10000000000; i++ {
fuzzTest()
}
}

/*Удаление паники: В изначальном коде при возникновении ошибки вызывалась паника (panic(err)), что приводило к нежелательному завершению работы программы. В моем коде я заменила эти вызовы паники на возврат ошибок функциями чтения и записи, с последующим контролем этих ошибок в функции main.

Устранение требования к формату файла: В изначальном коде не было проверки на соответствие формата файла, что могло привести к ошибкам при попытке прочитать файл, не удовлетворяющий ожидаемому формату. В моем коде я добавила проверки на ошибки после функций чтения, чтобы обеспечить правильное преждевременное завершение, если формат файла не поддерживается.

Обратимость преобразования данных: Исходный код не гарантировал, что преобразование данных в обе стороны (из бинарного в SSTable и обратно) будет порождать идентичные данные. В моем коде, методы записи и чтения обеспечивают обратимость этого преобразования, за исключением того, что порядок студентов в исходном и конечном массиве может отличаться.*/
166 changes: 166 additions & 0 deletions 03-fuzz/bogacheva/sstable-panesh-bogacheva.go.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
package main

import (
"bytes"
"encoding/binary"
"encoding/gob"
"errors"
"io"
"log"
"os"
"path"
"strconv"
"strings"

"github.com/cockroachdb/pebble/sstable"
"github.com/cockroachdb/pebble/vfs"
)

type Project struct {
Repo [59]byte
Mark uint8
}

type Student struct {
Name [32]byte
Login [16]byte
Group [8]byte
Practice [8]uint8
Project
Mark float32
}

func readBinary(filename string) ([]Student, error) {
file, err := os.Open(filename)
if err != nil {
return nil, err
}
defer file.Close()

var students []Student
for {
var st Student
err := binary.Read(file, binary.LittleEndian, &st)
if errors.Is(err, io.EOF) {
break
}
if err != nil {
return nil, err
}
students = append(students, st)
}

return students, nil
}

func writeBinary(students []Student, filename string) error {
file, err := os.Create(filename)
if err != nil {
return err
}
defer file.Close()

for _, s := range students {
err := binary.Write(file, binary.LittleEndian, &s)
if err != nil {
return err
}
}
return nil
}

func readSSTable(filename string) ([]Student, error) {
file, err := os.Open(filename)
if err != nil {
return nil, err
}

defer file.Close()

reader, err := sstable.NewReader(file, sstable.ReaderOptions{})
if err != nil {
return nil, err
}

i, err := reader.NewIter(nil, nil)
if err != nil {
return nil, err
}

students := []Student{}
for key, value := i.First(); key != nil; key, value = i.Next() {
dec := gob.NewDecoder(bytes.NewBuffer(value))
var s Student
err := dec.Decode(&s)
if err != nil {
return nil, err
}
students = append(students, s)
}

if err := i.Close(); err != nil {
return nil, err
}
return students, nil
}

func writeSSTable(students []Student, filename string) error {
mem := vfs.NewMem()
f, err := mem.Create(filename)
if err != nil {
return err
}

w := sstable.NewWriter(f, sstable.WriterOptions{})
for i, s := range students {
var sBuf bytes.Buffer
enc := gob.NewEncoder(&sBuf)
err = enc.Encode(s)
if err != nil {
return err
}

err = w.Set([]byte(strconv.Itoa(i)), sBuf.Bytes())
if err != nil {
return err
}
}

return w.Close()
}

func main() {
args := os.Args
filename := args[1]
ext := path.Ext(filename)
switch {
case ext == ".bin":
students, err := readBinary(filename)
if err != nil {
log.Printf("Failed to read file %s: %v\n", filename, err)
os.Exit(-1)
}
newFilename := strings.TrimSuffix(filename, ext) + ".sstable"
log.Println(filename, "->", newFilename)
if err = writeSSTable(students, newFilename); err != nil {
log.Printf("Failed to write file %s: %v\n", newFilename, err)
os.Exit(-1)
return
}
case ext == ".sstable":
students, err := readSSTable(filename)
if err != nil {
log.Printf("Failed to read file %s: %v\n", filename, err)
os.Exit(-1)
}
newFilename := strings.TrimSuffix(filename, ext) + ".bin"
log.Println(filename, "->", newFilename)
if err = writeBinary(students, newFilename); err != nil {
log.Printf("Failed to write file %s: %v\n", newFilename, err)
os.Exit(-1)
}
default:
log.Printf("Unsupported file extension: %s\n", ext)
os.Exit(-1)
}
}