-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(Writer): io.ErrShortWrite caused by even byte
Issues: #4
- Loading branch information
Showing
4 changed files
with
65 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
module github.com/myml/ar | ||
|
||
go 1.14 | ||
|
||
require github.com/google/martian v2.1.0+incompatible // indirect |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= | ||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
/* | ||
/* | ||
Copyright (c) 2013 Blake Smith <[email protected]> | ||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
|
@@ -28,7 +28,7 @@ import ( | |
) | ||
|
||
var ( | ||
ErrWriteTooLong = errors.New("ar: write too long") | ||
ErrWriteTooLong = errors.New("ar: write too long") | ||
) | ||
|
||
// Writer provides sequential writing of an ar archive. | ||
|
@@ -45,7 +45,7 @@ var ( | |
// } | ||
// io.Copy(archive, data) | ||
type Writer struct { | ||
w io.Writer | ||
w io.Writer | ||
nb int64 // number of unwritten bytes for the current file entry | ||
} | ||
|
||
|
@@ -92,7 +92,7 @@ func (aw *Writer) Write(b []byte) (n int, err error) { | |
|
||
if len(b)%2 == 1 { // data size must be aligned to an even byte | ||
n2, _ := aw.w.Write([]byte{'\n'}) | ||
return n+n2, err | ||
return n + n2, err | ||
} | ||
|
||
return | ||
|
@@ -122,3 +122,18 @@ func (aw *Writer) WriteHeader(hdr *Header) error { | |
|
||
return err | ||
} | ||
|
||
var _ io.ReaderFrom = &Writer{} | ||
|
||
// ReadFrom prevent returns io.ErrShortWrite when using io.Copy. This is to make io.Copy() to work correctly. | ||
func (aw *Writer) ReadFrom(r io.Reader) (written int64, err error) { | ||
written, err = io.Copy(aw.w, r) | ||
if err != nil { | ||
return written, err | ||
} | ||
if written%2 == 1 { // data size must be aligned to an even byte | ||
n2, err := aw.w.Write([]byte{'\n'}) | ||
return written + int64(n2), err | ||
} | ||
return written, err | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
/* | ||
/* | ||
Copyright (c) 2013 Blake Smith <[email protected]> | ||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
|
@@ -23,8 +23,10 @@ package ar | |
|
||
import ( | ||
"bytes" | ||
"io" | ||
"io/ioutil" | ||
"os" | ||
"strings" | ||
"testing" | ||
"time" | ||
) | ||
|
@@ -90,3 +92,39 @@ func TestWriteTooLong(t *testing.T) { | |
t.Errorf("Error should have been: %s", ErrWriteTooLong) | ||
} | ||
} | ||
|
||
// Use odd byte check error | ||
func TestShortWrite(t *testing.T) { | ||
body := strings.NewReader("Hello world!\n") | ||
|
||
hdr := new(Header) | ||
hdr.Size = body.Size() | ||
|
||
var buf bytes.Buffer | ||
writer := NewWriter(&buf) | ||
writer.WriteHeader(hdr) | ||
// Hide io.WriteTo interface and io.ReadFrom interface | ||
_, err := io.Copy(io.MultiWriter(writer), io.MultiReader(body)) | ||
if err != io.ErrShortWrite { | ||
t.Errorf("Error should have been: %s", io.ErrShortWrite) | ||
} | ||
} | ||
|
||
func TestWriteCopy(t *testing.T) { | ||
body := strings.NewReader("Hello world!\n") | ||
|
||
hdr := new(Header) | ||
hdr.Size = body.Size() | ||
|
||
var buf bytes.Buffer | ||
writer := NewWriter(&buf) | ||
writer.WriteHeader(hdr) | ||
// Only hide io.WriteTo interface | ||
wn, err := io.Copy(writer, io.MultiReader(body)) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
if wn != hdr.Size+1 { | ||
t.Errorf("Expected %d to equal %d", wn, hdr.Size+1) | ||
} | ||
} |