[bugfix] Fix images not being processed correctly sometimes (#437)

* bump exif-terminator to latest version

* add and test giant turnip from turnip.farm

* don't error if content property is nil
This commit is contained in:
tobi 2022-03-21 19:46:51 +01:00 committed by GitHub
parent 36b2f2b4e6
commit 25cab0e1f4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 245 additions and 46 deletions

4
go.mod
View file

@ -32,7 +32,7 @@ require (
github.com/spf13/viper v1.10.0 github.com/spf13/viper v1.10.0
github.com/stretchr/testify v1.7.0 github.com/stretchr/testify v1.7.0
github.com/superseriousbusiness/activity v1.0.1-0.20211113133524-56560b73ace8 github.com/superseriousbusiness/activity v1.0.1-0.20211113133524-56560b73ace8
github.com/superseriousbusiness/exif-terminator v0.1.0 github.com/superseriousbusiness/exif-terminator v0.2.0
github.com/superseriousbusiness/oauth2/v4 v4.3.2-SSB github.com/superseriousbusiness/oauth2/v4 v4.3.2-SSB
github.com/tdewolff/minify/v2 v2.9.22 github.com/tdewolff/minify/v2 v2.9.22
github.com/uptrace/bun v1.0.20 github.com/uptrace/bun v1.0.20
@ -59,7 +59,6 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dsoprea/go-exif/v3 v3.0.0-20210625224831-a6301f85c82b // indirect github.com/dsoprea/go-exif/v3 v3.0.0-20210625224831-a6301f85c82b // indirect
github.com/dsoprea/go-iptc v0.0.0-20200610044640-bc9ca208b413 // indirect github.com/dsoprea/go-iptc v0.0.0-20200610044640-bc9ca208b413 // indirect
github.com/dsoprea/go-jpeg-image-structure/v2 v2.0.0-20210512043942-b434301c6836 // indirect
github.com/dsoprea/go-logging v0.0.0-20200710184922-b02d349568dd // indirect github.com/dsoprea/go-logging v0.0.0-20200710184922-b02d349568dd // indirect
github.com/dsoprea/go-photoshop-info-format v0.0.0-20200610045659-121dd752914d // indirect github.com/dsoprea/go-photoshop-info-format v0.0.0-20200610045659-121dd752914d // indirect
github.com/dsoprea/go-png-image-structure/v2 v2.0.0-20210512210324-29b889a6093d // indirect github.com/dsoprea/go-png-image-structure/v2 v2.0.0-20210512210324-29b889a6093d // indirect
@ -103,6 +102,7 @@ require (
github.com/spf13/cast v1.4.1 // indirect github.com/spf13/cast v1.4.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/subosito/gotenv v1.2.0 // indirect github.com/subosito/gotenv v1.2.0 // indirect
github.com/superseriousbusiness/go-jpeg-image-structure/v2 v2.0.0-20220321154430-d89a106fdabe // indirect
github.com/tdewolff/parse/v2 v2.5.23 // indirect github.com/tdewolff/parse/v2 v2.5.23 // indirect
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect
github.com/ugorji/go/codec v1.2.6 // indirect github.com/ugorji/go/codec v1.2.6 // indirect

8
go.sum
View file

@ -155,8 +155,6 @@ github.com/dsoprea/go-exif/v3 v3.0.0-20210625224831-a6301f85c82b/go.mod h1:cg5SN
github.com/dsoprea/go-iptc v0.0.0-20200609062250-162ae6b44feb/go.mod h1:kYIdx9N9NaOyD7U6D+YtExN7QhRm+5kq7//yOsRXQtM= github.com/dsoprea/go-iptc v0.0.0-20200609062250-162ae6b44feb/go.mod h1:kYIdx9N9NaOyD7U6D+YtExN7QhRm+5kq7//yOsRXQtM=
github.com/dsoprea/go-iptc v0.0.0-20200610044640-bc9ca208b413 h1:YDRiMEm32T60Kpm35YzOK9ZHgjsS1Qrid+XskNcsdp8= github.com/dsoprea/go-iptc v0.0.0-20200610044640-bc9ca208b413 h1:YDRiMEm32T60Kpm35YzOK9ZHgjsS1Qrid+XskNcsdp8=
github.com/dsoprea/go-iptc v0.0.0-20200610044640-bc9ca208b413/go.mod h1:kYIdx9N9NaOyD7U6D+YtExN7QhRm+5kq7//yOsRXQtM= github.com/dsoprea/go-iptc v0.0.0-20200610044640-bc9ca208b413/go.mod h1:kYIdx9N9NaOyD7U6D+YtExN7QhRm+5kq7//yOsRXQtM=
github.com/dsoprea/go-jpeg-image-structure/v2 v2.0.0-20210512043942-b434301c6836 h1:KGCiMMWxODEMmI3+9Ms04l73efoqFVNKKKPbVyOvKrU=
github.com/dsoprea/go-jpeg-image-structure/v2 v2.0.0-20210512043942-b434301c6836/go.mod h1:WaARaUjQuSuDCDFAiU/GwzfxMTJBulfEhqEA2Tx6B4Y=
github.com/dsoprea/go-logging v0.0.0-20190624164917-c4f10aab7696/go.mod h1:Nm/x2ZUNRW6Fe5C3LxdY1PyZY5wmDv/s5dkPJ/VB3iA= github.com/dsoprea/go-logging v0.0.0-20190624164917-c4f10aab7696/go.mod h1:Nm/x2ZUNRW6Fe5C3LxdY1PyZY5wmDv/s5dkPJ/VB3iA=
github.com/dsoprea/go-logging v0.0.0-20200517223158-a10564966e9d/go.mod h1:7I+3Pe2o/YSU88W0hWlm9S22W7XI1JFNJ86U0zPKMf8= github.com/dsoprea/go-logging v0.0.0-20200517223158-a10564966e9d/go.mod h1:7I+3Pe2o/YSU88W0hWlm9S22W7XI1JFNJ86U0zPKMf8=
github.com/dsoprea/go-logging v0.0.0-20200710184922-b02d349568dd h1:l+vLbuxptsC6VQyQsfD7NnEC8BZuFpz45PgY+pH8YTg= github.com/dsoprea/go-logging v0.0.0-20200710184922-b02d349568dd h1:l+vLbuxptsC6VQyQsfD7NnEC8BZuFpz45PgY+pH8YTg=
@ -655,8 +653,10 @@ github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/superseriousbusiness/activity v1.0.1-0.20211113133524-56560b73ace8 h1:8Bwy6CSsT33/sF5FhjND4vr7jiJCaq4elNTAW4rUzVc= github.com/superseriousbusiness/activity v1.0.1-0.20211113133524-56560b73ace8 h1:8Bwy6CSsT33/sF5FhjND4vr7jiJCaq4elNTAW4rUzVc=
github.com/superseriousbusiness/activity v1.0.1-0.20211113133524-56560b73ace8/go.mod h1:ZY9xwFDucvp6zTvM6FQZGl8PSOofPBFIAy6gSc85XkY= github.com/superseriousbusiness/activity v1.0.1-0.20211113133524-56560b73ace8/go.mod h1:ZY9xwFDucvp6zTvM6FQZGl8PSOofPBFIAy6gSc85XkY=
github.com/superseriousbusiness/exif-terminator v0.1.0 h1:ePzfV0vcw+tm/haSOGzKbBTKkHAvyQLbCzfsdVkb3hM= github.com/superseriousbusiness/exif-terminator v0.2.0 h1:C21KOUr54E37qTqYS7WJX0J83sNzzCwBEy0KXyDprqU=
github.com/superseriousbusiness/exif-terminator v0.1.0/go.mod h1:pmlOKzkFZWmqaucLAtrRbZG0R5F3dbrcLWOcd7gAOLI= github.com/superseriousbusiness/exif-terminator v0.2.0/go.mod h1:DHJuKguXqyOVqB/oyOylutEDIZCbkYsn2GZFNSUDT9E=
github.com/superseriousbusiness/go-jpeg-image-structure/v2 v2.0.0-20220321154430-d89a106fdabe h1:ksl2oCx/Qo8sNDc3Grb8WGKBM9nkvhCm25uvlT86azE=
github.com/superseriousbusiness/go-jpeg-image-structure/v2 v2.0.0-20220321154430-d89a106fdabe/go.mod h1:gH4P6gN1V+wmIw5o97KGaa1RgXB/tVpC2UNzijhg3E4=
github.com/superseriousbusiness/oauth2/v4 v4.3.2-SSB h1:PtW2w6budTvRV2J5QAoSvThTHBuvh8t/+BXIZFAaBSc= github.com/superseriousbusiness/oauth2/v4 v4.3.2-SSB h1:PtW2w6budTvRV2J5QAoSvThTHBuvh8t/+BXIZFAaBSc=
github.com/superseriousbusiness/oauth2/v4 v4.3.2-SSB/go.mod h1:uYC/W92oVRJ49Vh1GcvTqpeFqHi+Ovrl2sMllQWRAEo= github.com/superseriousbusiness/oauth2/v4 v4.3.2-SSB/go.mod h1:uYC/W92oVRJ49Vh1GcvTqpeFqHi+Ovrl2sMllQWRAEo=
github.com/tdewolff/minify/v2 v2.9.22 h1:PlmaAakaJHdMMdTTwjjsuSwIxKqWPTlvjTj6a/g/ILU= github.com/tdewolff/minify/v2 v2.9.22 h1:PlmaAakaJHdMMdTTwjjsuSwIxKqWPTlvjTj6a/g/ILU=

View file

@ -50,17 +50,15 @@ type DereferencerStandardTestSuite struct {
dereferencer dereferencing.Dereferencer dereferencer dereferencing.Dereferencer
} }
func (suite *DereferencerStandardTestSuite) SetupSuite() { func (suite *DereferencerStandardTestSuite) SetupTest() {
testrig.InitTestConfig()
testrig.InitTestLog()
suite.testAccounts = testrig.NewTestAccounts() suite.testAccounts = testrig.NewTestAccounts()
suite.testRemoteStatuses = testrig.NewTestFediStatuses() suite.testRemoteStatuses = testrig.NewTestFediStatuses()
suite.testRemotePeople = testrig.NewTestFediPeople() suite.testRemotePeople = testrig.NewTestFediPeople()
suite.testRemoteGroups = testrig.NewTestFediGroups() suite.testRemoteGroups = testrig.NewTestFediGroups()
suite.testRemoteAttachments = testrig.NewTestFediAttachments("../../../testrig/media") suite.testRemoteAttachments = testrig.NewTestFediAttachments("../../../testrig/media")
}
func (suite *DereferencerStandardTestSuite) SetupTest() {
testrig.InitTestLog()
testrig.InitTestConfig()
suite.db = testrig.NewTestDB() suite.db = testrig.NewTestDB()
suite.storage = testrig.NewTestStorage() suite.storage = testrig.NewTestStorage()

View file

@ -131,6 +131,53 @@ func (suite *StatusTestSuite) TestDereferenceStatusWithMention() {
suite.False(m.Silent) suite.False(m.Silent)
} }
func (suite *StatusTestSuite) TestDereferenceStatusWithImageAndNoContent() {
fetchingAccount := suite.testAccounts["local_account_1"]
statusURL := testrig.URLMustParse("https://turnip.farm/users/turniplover6969/statuses/70c53e54-3146-42d5-a630-83c8b6c7c042")
status, statusable, new, err := suite.dereferencer.GetRemoteStatus(context.Background(), fetchingAccount.Username, statusURL, false, false)
suite.NoError(err)
suite.NotNil(status)
suite.NotNil(statusable)
suite.True(new)
// status values should be set
suite.Equal("https://turnip.farm/users/turniplover6969/statuses/70c53e54-3146-42d5-a630-83c8b6c7c042", status.URI)
suite.Equal("https://turnip.farm/@turniplover6969/70c53e54-3146-42d5-a630-83c8b6c7c042", status.URL)
suite.Equal("", status.Content)
suite.Equal("https://turnip.farm/users/turniplover6969", status.AccountURI)
suite.False(status.Local)
suite.Empty(status.ContentWarning)
suite.Equal(gtsmodel.VisibilityPublic, status.Visibility)
suite.Equal(ap.ObjectNote, status.ActivityStreamsType)
// status should be in the database
dbStatus, err := suite.db.GetStatusByURI(context.Background(), status.URI)
suite.NoError(err)
suite.Equal(status.ID, dbStatus.ID)
suite.True(dbStatus.Federated)
suite.True(dbStatus.Boostable)
suite.True(dbStatus.Replyable)
suite.True(dbStatus.Likeable)
// account should be in the database now too
account, err := suite.db.GetAccountByURI(context.Background(), status.AccountURI)
suite.NoError(err)
suite.NotNil(account)
suite.True(account.Discoverable)
suite.Equal("https://turnip.farm/users/turniplover6969", account.URI)
suite.Equal("I just think they're neat", account.Note)
suite.Equal("Turnip Lover 6969", account.DisplayName)
suite.Equal("turniplover6969", account.Username)
suite.NotNil(account.PublicKey)
suite.Nil(account.PrivateKey)
// we should have an attachment in the database
a := &gtsmodel.MediaAttachment{}
err = suite.db.GetWhere(context.Background(), []db.Where{{Key: "status_id", Value: status.ID}}, a)
suite.NoError(err)
}
func TestStatusTestSuite(t *testing.T) { func TestStatusTestSuite(t *testing.T) {
suite.Run(t, new(StatusTestSuite)) suite.Run(t, new(StatusTestSuite))
} }

View file

@ -125,7 +125,7 @@ func deriveThumbnail(r io.Reader, contentType string, createBlurhash bool) (*ima
} }
if err != nil { if err != nil {
return nil, err return nil, fmt.Errorf("error decoding image as %s: %s", contentType, err)
} }
if i == nil { if i == nil {
@ -151,7 +151,7 @@ func deriveThumbnail(r io.Reader, contentType string, createBlurhash bool) (*ima
tiny := resize.Thumbnail(32, 32, thumb, resize.NearestNeighbor) tiny := resize.Thumbnail(32, 32, thumb, resize.NearestNeighbor)
bh, err := blurhash.Encode(4, 3, tiny) bh, err := blurhash.Encode(4, 3, tiny)
if err != nil { if err != nil {
return nil, err return nil, fmt.Errorf("error creating blurhash: %s", err)
} }
im.blurhash = bh im.blurhash = bh
} }
@ -161,7 +161,7 @@ func deriveThumbnail(r io.Reader, contentType string, createBlurhash bool) (*ima
// Quality isn't extremely important for thumbnails, so 75 is "good enough" // Quality isn't extremely important for thumbnails, so 75 is "good enough"
Quality: 75, Quality: 75,
}); err != nil { }); err != nil {
return nil, err return nil, fmt.Errorf("error encoding thumbnail: %s", err)
} }
im.small = out.Bytes() im.small = out.Bytes()

View file

@ -260,6 +260,7 @@ func (p *ProcessingMedia) store(ctx context.Context) error {
if err != nil { if err != nil {
return fmt.Errorf("store: error executing data function: %s", err) return fmt.Errorf("store: error executing data function: %s", err)
} }
logrus.Tracef("store: reading %d bytes from data function for media %s", fileSize, p.attachment.URL)
// defer closing the reader when we're done with it // defer closing the reader when we're done with it
defer func() { defer func() {
@ -342,6 +343,7 @@ func (p *ProcessingMedia) store(ctx context.Context) error {
return p.postData(ctx) return p.postData(ctx)
} }
logrus.Tracef("store: finished storing initial data for attachment %s", p.attachment.URL)
return nil return nil
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

View file

@ -1460,7 +1460,7 @@ type ActivityWithSignature struct {
// A struct of accounts needs to be passed in because the activities will also be bundled along with // A struct of accounts needs to be passed in because the activities will also be bundled along with
// their requesting signatures. // their requesting signatures.
func NewTestActivities(accounts map[string]*gtsmodel.Account) map[string]ActivityWithSignature { func NewTestActivities(accounts map[string]*gtsmodel.Account) map[string]ActivityWithSignature {
dmForZork := newNote( dmForZork := newAPNote(
URLMustParse("http://fossbros-anonymous.io/users/foss_satan/statuses/5424b153-4553-4f30-9358-7b92f7cd42f6"), URLMustParse("http://fossbros-anonymous.io/users/foss_satan/statuses/5424b153-4553-4f30-9358-7b92f7cd42f6"),
URLMustParse("http://fossbros-anonymous.io/@foss_satan/5424b153-4553-4f30-9358-7b92f7cd42f6"), URLMustParse("http://fossbros-anonymous.io/@foss_satan/5424b153-4553-4f30-9358-7b92f7cd42f6"),
time.Now(), time.Now(),
@ -1470,15 +1470,17 @@ func NewTestActivities(accounts map[string]*gtsmodel.Account) map[string]Activit
[]*url.URL{URLMustParse("http://localhost:8080/users/the_mighty_zork")}, []*url.URL{URLMustParse("http://localhost:8080/users/the_mighty_zork")},
nil, nil,
true, true,
[]vocab.ActivityStreamsMention{}) []vocab.ActivityStreamsMention{},
createDmForZork := wrapNoteInCreate( nil,
)
createDmForZork := wrapAPNoteInCreate(
URLMustParse("http://fossbros-anonymous.io/users/foss_satan/statuses/5424b153-4553-4f30-9358-7b92f7cd42f6/activity"), URLMustParse("http://fossbros-anonymous.io/users/foss_satan/statuses/5424b153-4553-4f30-9358-7b92f7cd42f6/activity"),
URLMustParse("http://fossbros-anonymous.io/users/foss_satan"), URLMustParse("http://fossbros-anonymous.io/users/foss_satan"),
time.Now(), time.Now(),
dmForZork) dmForZork)
createDmForZorkSig, createDmForZorkDigest, creatDmForZorkDate := GetSignatureForActivity(createDmForZork, accounts["remote_account_1"].PublicKeyURI, accounts["remote_account_1"].PrivateKey, URLMustParse(accounts["local_account_1"].InboxURI)) createDmForZorkSig, createDmForZorkDigest, creatDmForZorkDate := GetSignatureForActivity(createDmForZork, accounts["remote_account_1"].PublicKeyURI, accounts["remote_account_1"].PrivateKey, URLMustParse(accounts["local_account_1"].InboxURI))
forwardedMessage := newNote( forwardedMessage := newAPNote(
URLMustParse("http://example.org/users/some_user/statuses/afaba698-5740-4e32-a702-af61aa543bc1"), URLMustParse("http://example.org/users/some_user/statuses/afaba698-5740-4e32-a702-af61aa543bc1"),
URLMustParse("http://example.org/@some_user/afaba698-5740-4e32-a702-af61aa543bc1"), URLMustParse("http://example.org/@some_user/afaba698-5740-4e32-a702-af61aa543bc1"),
time.Now(), time.Now(),
@ -1488,8 +1490,10 @@ func NewTestActivities(accounts map[string]*gtsmodel.Account) map[string]Activit
[]*url.URL{URLMustParse(pub.PublicActivityPubIRI)}, []*url.URL{URLMustParse(pub.PublicActivityPubIRI)},
nil, nil,
false, false,
[]vocab.ActivityStreamsMention{}) []vocab.ActivityStreamsMention{},
createForwardedMessage := wrapNoteInCreate( nil,
)
createForwardedMessage := wrapAPNoteInCreate(
URLMustParse("http://example.org/users/some_user/statuses/afaba698-5740-4e32-a702-af61aa543bc1/activity"), URLMustParse("http://example.org/users/some_user/statuses/afaba698-5740-4e32-a702-af61aa543bc1/activity"),
URLMustParse("http://example.org/users/some_user"), URLMustParse("http://example.org/users/some_user"),
time.Now(), time.Now(),
@ -1520,8 +1524,14 @@ func NewTestFediPeople() map[string]vocab.ActivityStreamsPerson {
} }
newPerson1Pub := &newPerson1Priv.PublicKey newPerson1Pub := &newPerson1Priv.PublicKey
turnipLover6969Priv, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
panic(err)
}
turnipLover6969Pub := &turnipLover6969Priv.PublicKey
return map[string]vocab.ActivityStreamsPerson{ return map[string]vocab.ActivityStreamsPerson{
"https://unknown-instance.com/users/brand_new_person": newPerson( "https://unknown-instance.com/users/brand_new_person": newAPPerson(
URLMustParse("https://unknown-instance.com/users/brand_new_person"), URLMustParse("https://unknown-instance.com/users/brand_new_person"),
URLMustParse("https://unknown-instance.com/users/brand_new_person/following"), URLMustParse("https://unknown-instance.com/users/brand_new_person/following"),
URLMustParse("https://unknown-instance.com/users/brand_new_person/followers"), URLMustParse("https://unknown-instance.com/users/brand_new_person/followers"),
@ -1541,6 +1551,26 @@ func NewTestFediPeople() map[string]vocab.ActivityStreamsPerson {
"image/png", "image/png",
false, false,
), ),
"https://turnip.farm/users/turniplover6969": newAPPerson(
URLMustParse("https://turnip.farm/users/turniplover6969"),
URLMustParse("https://turnip.farm/users/turniplover6969/following"),
URLMustParse("https://turnip.farm/users/turniplover6969/followers"),
URLMustParse("https://turnip.farm/users/turniplover6969/inbox"),
URLMustParse("https://turnip.farm/users/turniplover6969/outbox"),
URLMustParse("https://turnip.farm/users/turniplover6969/collections/featured"),
"turniplover6969",
"Turnip Lover 6969",
"I just think they're neat",
URLMustParse("https://turnip.farm/@turniplover6969"),
true,
URLMustParse("https://turnip.farm/users/turniplover6969#main-key"),
turnipLover6969Pub,
nil,
"image/jpeg",
nil,
"image/png",
false,
),
} }
} }
@ -1552,7 +1582,7 @@ func NewTestFediGroups() map[string]vocab.ActivityStreamsGroup {
newGroup1Pub := &newGroup1Priv.PublicKey newGroup1Pub := &newGroup1Priv.PublicKey
return map[string]vocab.ActivityStreamsGroup{ return map[string]vocab.ActivityStreamsGroup{
"https://unknown-instance.com/groups/some_group": newGroup( "https://unknown-instance.com/groups/some_group": newAPGroup(
URLMustParse("https://unknown-instance.com/groups/some_group"), URLMustParse("https://unknown-instance.com/groups/some_group"),
URLMustParse("https://unknown-instance.com/groups/some_group/following"), URLMustParse("https://unknown-instance.com/groups/some_group/following"),
URLMustParse("https://unknown-instance.com/groups/some_group/followers"), URLMustParse("https://unknown-instance.com/groups/some_group/followers"),
@ -1592,6 +1622,11 @@ func NewTestFediAttachments(relativePath string) map[string]RemoteAttachmentFile
panic(err) panic(err)
} }
massiveFuckingTurnipBytes, err := os.ReadFile(fmt.Sprintf("%s/giant-turnip-world-record.jpg", relativePath))
if err != nil {
panic(err)
}
return map[string]RemoteAttachmentFile{ return map[string]RemoteAttachmentFile{
"https://s3-us-west-2.amazonaws.com/plushcity/media_attachments/files/106/867/380/219/163/828/original/88e8758c5f011439.jpg": { "https://s3-us-west-2.amazonaws.com/plushcity/media_attachments/files/106/867/380/219/163/828/original/88e8758c5f011439.jpg": {
Data: beeBytes, Data: beeBytes,
@ -1601,12 +1636,16 @@ func NewTestFediAttachments(relativePath string) map[string]RemoteAttachmentFile
Data: thoughtsOfDogBytes, Data: thoughtsOfDogBytes,
ContentType: "image/jpeg", ContentType: "image/jpeg",
}, },
"https://turnip.farm/attachments/f17843c7-015e-4251-9b5a-91389c49ee57.jpg": {
Data: massiveFuckingTurnipBytes,
ContentType: "image/jpeg",
},
} }
} }
func NewTestFediStatuses() map[string]vocab.ActivityStreamsNote { func NewTestFediStatuses() map[string]vocab.ActivityStreamsNote {
return map[string]vocab.ActivityStreamsNote{ return map[string]vocab.ActivityStreamsNote{
"https://unknown-instance.com/users/brand_new_person/statuses/01FE4NTHKWW7THT67EF10EB839": newNote( "https://unknown-instance.com/users/brand_new_person/statuses/01FE4NTHKWW7THT67EF10EB839": newAPNote(
URLMustParse("https://unknown-instance.com/users/brand_new_person/statuses/01FE4NTHKWW7THT67EF10EB839"), URLMustParse("https://unknown-instance.com/users/brand_new_person/statuses/01FE4NTHKWW7THT67EF10EB839"),
URLMustParse("https://unknown-instance.com/users/@brand_new_person/01FE4NTHKWW7THT67EF10EB839"), URLMustParse("https://unknown-instance.com/users/@brand_new_person/01FE4NTHKWW7THT67EF10EB839"),
time.Now(), time.Now(),
@ -1618,9 +1657,10 @@ func NewTestFediStatuses() map[string]vocab.ActivityStreamsNote {
}, },
[]*url.URL{}, []*url.URL{},
false, false,
[]vocab.ActivityStreamsMention{}, nil,
nil,
), ),
"https://unknown-instance.com/users/brand_new_person/statuses/01FE5Y30E3W4P7TRE0R98KAYQV": newNote( "https://unknown-instance.com/users/brand_new_person/statuses/01FE5Y30E3W4P7TRE0R98KAYQV": newAPNote(
URLMustParse("https://unknown-instance.com/users/brand_new_person/statuses/01FE5Y30E3W4P7TRE0R98KAYQV"), URLMustParse("https://unknown-instance.com/users/brand_new_person/statuses/01FE5Y30E3W4P7TRE0R98KAYQV"),
URLMustParse("https://unknown-instance.com/users/@brand_new_person/01FE5Y30E3W4P7TRE0R98KAYQV"), URLMustParse("https://unknown-instance.com/users/@brand_new_person/01FE5Y30E3W4P7TRE0R98KAYQV"),
time.Now(), time.Now(),
@ -1633,11 +1673,34 @@ func NewTestFediStatuses() map[string]vocab.ActivityStreamsNote {
[]*url.URL{}, []*url.URL{},
false, false,
[]vocab.ActivityStreamsMention{ []vocab.ActivityStreamsMention{
newMention( newAPMention(
URLMustParse("http://localhost:8080/users/the_mighty_zork"), URLMustParse("http://localhost:8080/users/the_mighty_zork"),
"@the_mighty_zork@localhost:8080", "@the_mighty_zork@localhost:8080",
), ),
}, },
nil,
),
"https://turnip.farm/users/turniplover6969/statuses/70c53e54-3146-42d5-a630-83c8b6c7c042": newAPNote(
URLMustParse("https://turnip.farm/users/turniplover6969/statuses/70c53e54-3146-42d5-a630-83c8b6c7c042"),
URLMustParse("https://turnip.farm/@turniplover6969/70c53e54-3146-42d5-a630-83c8b6c7c042"),
time.Now(),
"",
"",
URLMustParse("https://turnip.farm/users/turniplover6969"),
[]*url.URL{
URLMustParse(pub.PublicActivityPubIRI),
},
[]*url.URL{},
false,
nil,
[]vocab.ActivityStreamsImage{
newAPImage(
URLMustParse("https://turnip.farm/attachments/f17843c7-015e-4251-9b5a-91389c49ee57.jpg"),
"image/jpeg",
"",
"",
),
},
), ),
} }
} }
@ -1799,7 +1862,7 @@ func GetSignatureForDereference(pubKeyID string, privkey crypto.PrivateKey, dest
return return
} }
func newPerson( func newAPPerson(
profileIDURI *url.URL, profileIDURI *url.URL,
followingURI *url.URL, followingURI *url.URL,
followersURI *url.URL, followersURI *url.URL,
@ -1982,7 +2045,7 @@ func newPerson(
return person return person
} }
func newGroup( func newAPGroup(
profileIDURI *url.URL, profileIDURI *url.URL,
followingURI *url.URL, followingURI *url.URL,
followersURI *url.URL, followersURI *url.URL,
@ -2165,7 +2228,7 @@ func newGroup(
return group return group
} }
func newMention(uri *url.URL, namestring string) vocab.ActivityStreamsMention { func newAPMention(uri *url.URL, namestring string) vocab.ActivityStreamsMention {
mention := streams.NewActivityStreamsMention() mention := streams.NewActivityStreamsMention()
hrefProp := streams.NewActivityStreamsHrefProperty() hrefProp := streams.NewActivityStreamsHrefProperty()
@ -2179,8 +2242,38 @@ func newMention(uri *url.URL, namestring string) vocab.ActivityStreamsMention {
return mention return mention
} }
// newNote returns a new activity streams note for the given parameters func newAPImage(url *url.URL, mediaType string, imageDescription string, blurhash string) vocab.ActivityStreamsImage {
func newNote( image := streams.NewActivityStreamsImage()
if url != nil {
urlProp := streams.NewActivityStreamsUrlProperty()
urlProp.AppendIRI(url)
image.SetActivityStreamsUrl(urlProp)
}
if mediaType != "" {
mediaTypeProp := streams.NewActivityStreamsMediaTypeProperty()
mediaTypeProp.Set(mediaType)
image.SetActivityStreamsMediaType(mediaTypeProp)
}
if imageDescription != "" {
nameProp := streams.NewActivityStreamsNameProperty()
nameProp.AppendXMLSchemaString(imageDescription)
image.SetActivityStreamsName(nameProp)
}
if blurhash != "" {
blurhashProp := streams.NewTootBlurhashProperty()
blurhashProp.Set(blurhash)
image.SetTootBlurhash(blurhashProp)
}
return image
}
// newAPNote returns a new activity streams note for the given parameters
func newAPNote(
noteID *url.URL, noteID *url.URL,
noteURL *url.URL, noteURL *url.URL,
noteCreatedAt time.Time, noteCreatedAt time.Time,
@ -2190,7 +2283,8 @@ func newNote(
noteTo []*url.URL, noteTo []*url.URL,
noteCC []*url.URL, noteCC []*url.URL,
noteSensitive bool, noteSensitive bool,
noteMentions []vocab.ActivityStreamsMention) vocab.ActivityStreamsNote { noteMentions []vocab.ActivityStreamsMention,
noteAttachments []vocab.ActivityStreamsImage) vocab.ActivityStreamsNote {
// create the note itself // create the note itself
note := streams.NewActivityStreamsNote() note := streams.NewActivityStreamsNote()
@ -2255,21 +2349,27 @@ func newNote(
note.SetActivityStreamsCc(cc) note.SetActivityStreamsCc(cc)
} }
// set note tags
tag := streams.NewActivityStreamsTagProperty()
// mentions // mentions
tag := streams.NewActivityStreamsTagProperty()
for _, m := range noteMentions { for _, m := range noteMentions {
tag.AppendActivityStreamsMention(m) tag.AppendActivityStreamsMention(m)
} }
note.SetActivityStreamsTag(tag) note.SetActivityStreamsTag(tag)
// append any attachments as ActivityStreamsImage
if noteAttachments != nil {
attachmentProperty := streams.NewActivityStreamsAttachmentProperty()
for _, a := range noteAttachments {
attachmentProperty.AppendActivityStreamsImage(a)
}
note.SetActivityStreamsAttachment(attachmentProperty)
}
return note return note
} }
// wrapNoteInCreate wraps the given activity streams note in a Create activity streams action // wrapAPNoteInCreate wraps the given activity streams note in a Create activity streams action
func wrapNoteInCreate(createID *url.URL, createActor *url.URL, createPublished time.Time, createNote vocab.ActivityStreamsNote) vocab.ActivityStreamsCreate { func wrapAPNoteInCreate(createID *url.URL, createActor *url.URL, createPublished time.Time, createNote vocab.ActivityStreamsNote) vocab.ActivityStreamsCreate {
// create the.... create // create the.... create
create := streams.NewActivityStreamsCreate() create := streams.NewActivityStreamsCreate()

View file

@ -23,7 +23,7 @@ import (
"fmt" "fmt"
"io" "io"
jpegstructure "github.com/dsoprea/go-jpeg-image-structure/v2" jpegstructure "github.com/superseriousbusiness/go-jpeg-image-structure/v2"
) )
var markerLen = map[byte]int{ var markerLen = map[byte]int{

View file

@ -0,0 +1,47 @@
/*
exif-terminator
Copyright (C) 2022 SuperSeriousBusiness admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package terminator
import "fmt"
var logger ErrorLogger
func init() {
logger = &defaultErrorLogger{}
}
// ErrorLogger denotes a generic error logging function.
type ErrorLogger interface {
Error(args ...interface{})
}
type defaultErrorLogger struct{}
func (d *defaultErrorLogger) Error(args ...interface{}) {
fmt.Println(args...)
}
// SetErrorLogger allows a user of the exif-terminator library
// to set the logger that will be used for error logging.
//
// If it is not set, the default error logger will be used, which
// just prints errors to stdout.
func SetErrorLogger(errorLogger ErrorLogger) {
logger = errorLogger
}

View file

@ -25,7 +25,7 @@ import (
"fmt" "fmt"
"io" "io"
jpegstructure "github.com/dsoprea/go-jpeg-image-structure/v2" jpegstructure "github.com/superseriousbusiness/go-jpeg-image-structure/v2"
pngstructure "github.com/dsoprea/go-png-image-structure/v2" pngstructure "github.com/dsoprea/go-png-image-structure/v2"
) )
@ -109,8 +109,11 @@ func scanAndClose(scanner *bufio.Scanner, writer io.WriteCloser) {
// until the pipeReader starts being read by the caller, which // until the pipeReader starts being read by the caller, which
// is why we do this asynchronously // is why we do this asynchronously
go func() { go func() {
defer writer.Close()
for scanner.Scan() { for scanner.Scan() {
} }
writer.Close() if scanner.Err() != nil {
logger.Error(scanner.Err())
}
}() }()
} }

View file

@ -232,8 +232,8 @@ func (js *JpegSplitter) readSegment(data []byte) (count int, err error) {
err = binary.Read(b, binary.BigEndian, &l) err = binary.Read(b, binary.BigEndian, &l)
log.PanicIf(err) log.PanicIf(err)
if l <= 2 { if l < 2 {
log.Panicf("length of size read for non-special marker (%02x) is unexpectedly not more than two.", markerId) log.Panicf("length of size read for non-special marker (%02x) is unexpectedly less than two.", markerId)
} }
// (l includes the bytes of the length itself.) // (l includes the bytes of the length itself.)

6
vendor/modules.txt vendored
View file

@ -57,7 +57,6 @@ github.com/dsoprea/go-exif/v3/undefined
github.com/dsoprea/go-iptc github.com/dsoprea/go-iptc
# github.com/dsoprea/go-jpeg-image-structure/v2 v2.0.0-20210512043942-b434301c6836 # github.com/dsoprea/go-jpeg-image-structure/v2 v2.0.0-20210512043942-b434301c6836
## explicit; go 1.12 ## explicit; go 1.12
github.com/dsoprea/go-jpeg-image-structure/v2
# github.com/dsoprea/go-logging v0.0.0-20200710184922-b02d349568dd # github.com/dsoprea/go-logging v0.0.0-20200710184922-b02d349568dd
## explicit; go 1.13 ## explicit; go 1.13
github.com/dsoprea/go-logging github.com/dsoprea/go-logging
@ -471,9 +470,12 @@ github.com/superseriousbusiness/activity/streams/values/rfc2045
github.com/superseriousbusiness/activity/streams/values/rfc5988 github.com/superseriousbusiness/activity/streams/values/rfc5988
github.com/superseriousbusiness/activity/streams/values/string github.com/superseriousbusiness/activity/streams/values/string
github.com/superseriousbusiness/activity/streams/vocab github.com/superseriousbusiness/activity/streams/vocab
# github.com/superseriousbusiness/exif-terminator v0.1.0 # github.com/superseriousbusiness/exif-terminator v0.2.0
## explicit; go 1.17 ## explicit; go 1.17
github.com/superseriousbusiness/exif-terminator github.com/superseriousbusiness/exif-terminator
# github.com/superseriousbusiness/go-jpeg-image-structure/v2 v2.0.0-20220321154430-d89a106fdabe
## explicit; go 1.17
github.com/superseriousbusiness/go-jpeg-image-structure/v2
# github.com/superseriousbusiness/oauth2/v4 v4.3.2-SSB # github.com/superseriousbusiness/oauth2/v4 v4.3.2-SSB
## explicit; go 1.13 ## explicit; go 1.13
github.com/superseriousbusiness/oauth2/v4 github.com/superseriousbusiness/oauth2/v4