Disallow operating on binary files in gist
This commit is contained in:
parent
50c49df41a
commit
973fbb0925
8 changed files with 120 additions and 4 deletions
1
go.mod
1
go.mod
|
|
@ -11,6 +11,7 @@ require (
|
|||
github.com/cli/safeexec v1.0.0
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0
|
||||
github.com/enescakir/emoji v1.0.0
|
||||
github.com/gabriel-vasile/mimetype v1.1.2
|
||||
github.com/google/go-cmp v0.5.2
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
|
||||
github.com/hashicorp/go-version v1.2.1
|
||||
|
|
|
|||
2
go.sum
2
go.sum
|
|
@ -74,6 +74,8 @@ github.com/enescakir/emoji v1.0.0/go.mod h1:Bt1EKuLnKDTYpLALApstIkAjdDrS/8IAgTkK
|
|||
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/gabriel-vasile/mimetype v1.1.2 h1:gaPnPcNor5aZSVCJVSGipcpbgMWiAAj9z182ocSGbHU=
|
||||
github.com/gabriel-vasile/mimetype v1.1.2/go.mod h1:6CDPel/o/3/s4+bp6kIbsWATq8pmgOisOPG40CJa6To=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
|
|
|
|||
|
|
@ -30,8 +30,7 @@ type CreateOptions struct {
|
|||
Public bool
|
||||
Filenames []string
|
||||
FilenameOverride string
|
||||
|
||||
WebMode bool
|
||||
WebMode bool
|
||||
|
||||
HttpClient func() (*http.Client, error)
|
||||
}
|
||||
|
|
@ -164,6 +163,8 @@ func processFiles(stdin io.ReadCloser, filenameOverride string, filenames []stri
|
|||
var filename string
|
||||
var content []byte
|
||||
var err error
|
||||
var isBinary bool
|
||||
|
||||
if f == "-" {
|
||||
if filenameOverride != "" {
|
||||
filename = filenameOverride
|
||||
|
|
@ -180,6 +181,16 @@ func processFiles(stdin io.ReadCloser, filenameOverride string, filenames []stri
|
|||
if err != nil {
|
||||
return fs, fmt.Errorf("failed to read file %s: %w", f, err)
|
||||
}
|
||||
|
||||
isBinary, err = shared.IsBinaryContents(content)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if isBinary {
|
||||
return nil, fmt.Errorf("binary file not supported")
|
||||
}
|
||||
|
||||
filename = path.Base(f)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -148,6 +148,15 @@ func editRun(opts *EditOptions) error {
|
|||
return fmt.Errorf("gist has no file %q", filename)
|
||||
}
|
||||
|
||||
isBinary, err := shared.IsBinaryContents([]byte(gist.Files[filename].Content))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if isBinary {
|
||||
return fmt.Errorf("Editing binary files not supported")
|
||||
}
|
||||
|
||||
editorCommand, err := cmdutil.DetermineEditor(opts.Config)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
|||
|
|
@ -301,7 +301,6 @@ func Test_editRun(t *testing.T) {
|
|||
io.SetStdoutTTY(!tt.nontty)
|
||||
io.SetStdinTTY(!tt.nontty)
|
||||
tt.opts.IO = io
|
||||
|
||||
tt.opts.Selector = "1234"
|
||||
|
||||
tt.opts.Config = func() (config.Config, error) {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import (
|
|||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/gabriel-vasile/mimetype"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
|
@ -147,3 +148,34 @@ pagination:
|
|||
|
||||
return gists, nil
|
||||
}
|
||||
|
||||
func IsBinaryFile(file string) (bool, error) {
|
||||
detectedMime, err := mimetype.DetectFile(file)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
isBinary := true
|
||||
|
||||
for mime := detectedMime; mime != nil; mime = mime.Parent() {
|
||||
if mime.Is("text/plain") {
|
||||
isBinary = false
|
||||
}
|
||||
}
|
||||
|
||||
return isBinary, nil
|
||||
}
|
||||
|
||||
func IsBinaryContents(contents []byte) (bool, error) {
|
||||
detectedMime := mimetype.Detect(contents)
|
||||
|
||||
isBinary := true
|
||||
|
||||
for mime := detectedMime; mime != nil; mime = mime.Parent() {
|
||||
if mime.Is("text/plain") {
|
||||
isBinary = false
|
||||
}
|
||||
}
|
||||
|
||||
return isBinary, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,3 +50,34 @@ func Test_GetGistIDFromURL(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsBinaryContents(t *testing.T) {
|
||||
tests := []struct {
|
||||
fileContent []byte
|
||||
want bool
|
||||
}{
|
||||
{
|
||||
want: false,
|
||||
fileContent: []byte("package main"),
|
||||
},
|
||||
{
|
||||
want: true,
|
||||
fileContent: []byte{239, 191, 189, 239, 191, 189, 239, 191, 189, 239,
|
||||
191, 189, 239, 191, 189, 16, 74, 70, 73, 70, 239, 191, 189, 1, 1, 1,
|
||||
1, 44, 1, 44, 239, 191, 189, 239, 191, 189, 239, 191, 189, 239, 191,
|
||||
189, 239, 191, 189, 67, 239, 191, 189, 8, 6, 6, 7, 6, 5, 8, 7, 7, 7,
|
||||
9, 9, 8, 10, 12, 20, 10, 12, 11, 11, 12, 25, 18, 19, 15, 20, 29, 26,
|
||||
31, 30, 29, 26, 28, 28, 32, 36, 46, 39, 32, 34, 44, 35, 28, 28, 40,
|
||||
55, 41, 44, 48, 49, 52, 52, 52, 31, 39, 57, 61, 56, 50, 60, 46, 51,
|
||||
52, 50, 239, 191, 189, 239, 191, 189, 239, 191, 189, 67, 1, 9, 9, 9, 12},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
isBinary, err := IsBinaryContents(tt.fileContent)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
assert.Equal(t, tt.want, isBinary)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -118,6 +118,15 @@ func viewRun(opts *ViewOptions) error {
|
|||
defer opts.IO.StopPager()
|
||||
|
||||
render := func(gf *shared.GistFile) error {
|
||||
isBinary, err := shared.IsBinaryContents([]byte(gf.Content))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if isBinary {
|
||||
gf.Content = "Skipping rendering binary content..."
|
||||
}
|
||||
|
||||
if strings.Contains(gf.Type, "markdown") && !opts.Raw {
|
||||
rendered, err := markdown.Render(gf.Content, markdownStyle, "")
|
||||
if err != nil {
|
||||
|
|
@ -134,6 +143,7 @@ func viewRun(opts *ViewOptions) error {
|
|||
_, err := fmt.Fprint(opts.IO.Out, "\n")
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -142,6 +152,16 @@ func viewRun(opts *ViewOptions) error {
|
|||
if !ok {
|
||||
return fmt.Errorf("gist has no such file: %q", opts.Filename)
|
||||
}
|
||||
|
||||
isBinary, err := shared.IsBinaryContents([]byte(gistFile.Content))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if isBinary {
|
||||
return fmt.Errorf("Error: file contents is binary")
|
||||
}
|
||||
|
||||
return render(gistFile)
|
||||
}
|
||||
|
||||
|
|
@ -154,8 +174,19 @@ func viewRun(opts *ViewOptions) error {
|
|||
for fn := range gist.Files {
|
||||
filenames = append(filenames, fn)
|
||||
}
|
||||
sort.Strings(filenames)
|
||||
|
||||
if len(filenames) == 1 {
|
||||
isBinary, err := shared.IsBinaryContents([]byte(gist.Files[filenames[0]].Content))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if isBinary {
|
||||
return fmt.Errorf("Error: file contents is binary")
|
||||
}
|
||||
}
|
||||
|
||||
sort.Strings(filenames)
|
||||
if opts.ListFiles {
|
||||
for _, fn := range filenames {
|
||||
fmt.Fprintln(opts.IO.Out, fn)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue