summaryrefslogtreecommitdiff
path: root/vendor/github.com/superseriousbusiness/exifremove
diff options
context:
space:
mode:
authorLibravatar Tobi Smethurst <31960611+tsmethurst@users.noreply.github.com>2021-08-12 21:03:24 +0200
committerLibravatar GitHub <noreply@github.com>2021-08-12 21:03:24 +0200
commit98263a7de64269898a2f81207e38943b5c8e8653 (patch)
tree743c90f109a6c5d27832d1dcef2388d939f0f77a /vendor/github.com/superseriousbusiness/exifremove
parentText duplication fix (#137) (diff)
downloadgotosocial-98263a7de64269898a2f81207e38943b5c8e8653.tar.xz
Grand test fixup (#138)
* start fixing up tests * fix up tests + automate with drone * fiddle with linting * messing about with drone.yml * some more fiddling * hmmm * add cache * add vendor directory * verbose * ci updates * update some little things * update sig
Diffstat (limited to 'vendor/github.com/superseriousbusiness/exifremove')
-rw-r--r--vendor/github.com/superseriousbusiness/exifremove/LICENSE21
-rw-r--r--vendor/github.com/superseriousbusiness/exifremove/pkg/exifremove/exifremove.go140
-rw-r--r--vendor/github.com/superseriousbusiness/exifremove/pkg/exifremove/png_crc_fix.go104
3 files changed, 265 insertions, 0 deletions
diff --git a/vendor/github.com/superseriousbusiness/exifremove/LICENSE b/vendor/github.com/superseriousbusiness/exifremove/LICENSE
new file mode 100644
index 000000000..3ba9c83c6
--- /dev/null
+++ b/vendor/github.com/superseriousbusiness/exifremove/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2019 scott lee davis
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/github.com/superseriousbusiness/exifremove/pkg/exifremove/exifremove.go b/vendor/github.com/superseriousbusiness/exifremove/pkg/exifremove/exifremove.go
new file mode 100644
index 000000000..d9e7e2ad1
--- /dev/null
+++ b/vendor/github.com/superseriousbusiness/exifremove/pkg/exifremove/exifremove.go
@@ -0,0 +1,140 @@
+package exifremove
+
+import (
+ "bytes"
+ "encoding/binary"
+ "errors"
+ "fmt"
+ "image/jpeg"
+ "image/png"
+
+ "github.com/dsoprea/go-exif"
+ jpegstructure "github.com/dsoprea/go-jpeg-image-structure"
+ pngstructure "github.com/dsoprea/go-png-image-structure"
+ "github.com/h2non/filetype"
+)
+
+func Remove(data []byte) ([]byte, error) {
+
+ const (
+ JpegMediaType = "jpeg"
+ PngMediaType = "png"
+ OtherMediaType = "other"
+ StartBytes = 0
+ EndBytes = 0
+ )
+
+ type MediaContext struct {
+ MediaType string
+ RootIfd *exif.Ifd
+ RawExif []byte
+ Media interface{}
+ }
+
+ filtered := []byte{}
+
+ head := make([]byte, 261)
+ _, err := bytes.NewReader(data).Read(head)
+ if err != nil {
+ return nil, fmt.Errorf("could not read first 261 bytes of data: %s", err)
+ }
+ imagetype, err := filetype.Match(head)
+ if err != nil {
+ return nil, fmt.Errorf("error matching first 261 bytes of image to valid type: %s", err)
+ }
+
+ switch imagetype.MIME.Subtype {
+ case "jpeg":
+ jmp := jpegstructure.NewJpegMediaParser()
+ sl, err := jmp.ParseBytes(data)
+ if err != nil {
+ return nil, err
+ }
+
+ _, rawExif, err := sl.Exif()
+ if err != nil {
+ return data, nil
+ }
+
+ startExifBytes := StartBytes
+ endExifBytes := EndBytes
+
+ if bytes.Contains(data, rawExif) {
+ for i := 0; i < len(data)-len(rawExif); i++ {
+ if bytes.Compare(data[i:i+len(rawExif)], rawExif) == 0 {
+ startExifBytes = i
+ endExifBytes = i + len(rawExif)
+ break
+ }
+ }
+ fill := make([]byte, len(data[startExifBytes:endExifBytes]))
+ copy(data[startExifBytes:endExifBytes], fill)
+ }
+
+ filtered = data
+
+ _, err = jpeg.Decode(bytes.NewReader(filtered))
+ if err != nil {
+ return nil, errors.New("EXIF removal corrupted " + err.Error())
+ }
+ case "png":
+ pmp := pngstructure.NewPngMediaParser()
+ cs, err := pmp.ParseBytes(data)
+ if err != nil {
+ return nil, err
+ }
+
+ _, rawExif, err := cs.Exif()
+ if err != nil {
+ return data, nil
+ }
+
+ startExifBytes := StartBytes
+ endExifBytes := EndBytes
+
+ if bytes.Contains(data, rawExif) {
+ for i := 0; i < len(data)-len(rawExif); i++ {
+ if bytes.Compare(data[i:i+len(rawExif)], rawExif) == 0 {
+ startExifBytes = i
+ endExifBytes = i + len(rawExif)
+ break
+ }
+ }
+ fill := make([]byte, len(data[startExifBytes:endExifBytes]))
+ copy(data[startExifBytes:endExifBytes], fill)
+ }
+
+ filtered = data
+
+ chunks := readPNGChunks(bytes.NewReader(filtered))
+
+ for _, chunk := range chunks {
+ if !chunk.CRCIsValid() {
+ offset := int(chunk.Offset) + 8 + int(chunk.Length)
+ crc := chunk.CalculateCRC()
+
+ buf := new(bytes.Buffer)
+ binary.Write(buf, binary.BigEndian, crc)
+ crcBytes := buf.Bytes()
+
+ copy(filtered[offset:], crcBytes)
+ }
+ }
+
+ chunks = readPNGChunks(bytes.NewReader(filtered))
+ for _, chunk := range chunks {
+ if !chunk.CRCIsValid() {
+ return nil, errors.New("EXIF removal failed CRC")
+ }
+ }
+
+ _, err = png.Decode(bytes.NewReader(filtered))
+ if err != nil {
+ return nil, errors.New("EXIF removal corrupted " + err.Error())
+ }
+ default:
+ return nil, errors.New("filetype not recognised")
+ }
+
+ return filtered, nil
+}
diff --git a/vendor/github.com/superseriousbusiness/exifremove/pkg/exifremove/png_crc_fix.go b/vendor/github.com/superseriousbusiness/exifremove/pkg/exifremove/png_crc_fix.go
new file mode 100644
index 000000000..390e5e515
--- /dev/null
+++ b/vendor/github.com/superseriousbusiness/exifremove/pkg/exifremove/png_crc_fix.go
@@ -0,0 +1,104 @@
+package exifremove
+
+// borrowed heavily from https://github.com/landaire/png-crc-fix/blob/master/main.go
+
+import (
+ "bytes"
+ "encoding/binary"
+ "fmt"
+ "hash/crc32"
+ "io"
+ "os"
+)
+
+const chunkStartOffset = 8
+const endChunk = "IEND"
+
+type pngChunk struct {
+ Offset int64
+ Length uint32
+ Type [4]byte
+ Data []byte
+ CRC uint32
+}
+
+func (p pngChunk) String() string {
+ return fmt.Sprintf("%s@%x - %X - Valid CRC? %v", p.Type, p.Offset, p.CRC, p.CRCIsValid())
+}
+
+func (p pngChunk) Bytes() []byte {
+ var buffer bytes.Buffer
+
+ binary.Write(&buffer, binary.BigEndian, p.Type)
+ buffer.Write(p.Data)
+
+ return buffer.Bytes()
+}
+
+func (p pngChunk) CRCIsValid() bool {
+ return p.CRC == p.CalculateCRC()
+}
+
+func (p pngChunk) CalculateCRC() uint32 {
+ crcTable := crc32.MakeTable(crc32.IEEE)
+
+ return crc32.Checksum(p.Bytes(), crcTable)
+}
+
+func (p pngChunk) CRCOffset() int64 {
+ return p.Offset + int64(8+p.Length)
+}
+
+func readPNGChunks(reader io.ReadSeeker) []pngChunk {
+ chunks := []pngChunk{}
+
+ reader.Seek(chunkStartOffset, os.SEEK_SET)
+
+ readChunk := func() (*pngChunk, error) {
+ var chunk pngChunk
+ chunk.Offset, _ = reader.Seek(0, os.SEEK_CUR)
+
+ binary.Read(reader, binary.BigEndian, &chunk.Length)
+
+ chunk.Data = make([]byte, chunk.Length)
+
+ err := binary.Read(reader, binary.BigEndian, &chunk.Type)
+ if err != nil {
+ goto read_error
+ }
+
+ if read, err := reader.Read(chunk.Data); read == 0 || err != nil {
+ goto read_error
+ }
+
+ err = binary.Read(reader, binary.BigEndian, &chunk.CRC)
+ if err != nil {
+ goto read_error
+ }
+
+ return &chunk, nil
+
+ read_error:
+ return nil, fmt.Errorf("Read error")
+ }
+
+ chunk, err := readChunk()
+ if err != nil {
+ return chunks
+ }
+
+ chunks = append(chunks, *chunk)
+
+ // Read the first chunk
+ for string(chunks[len(chunks)-1].Type[:]) != endChunk {
+
+ chunk, err := readChunk()
+ if err != nil {
+ break
+ }
+
+ chunks = append(chunks, *chunk)
+ }
+
+ return chunks
+}