From 385e6d21d2be069ff4aa733afc9ca14289bb7056 Mon Sep 17 00:00:00 2001 From: wussler Date: Tue, 1 Dec 2020 18:09:25 +0100 Subject: [PATCH] Drop regex for canonicalization (#102) * Drop regex for canonicalization * Fix CI --- .golangci.yml | 1 + CHANGELOG.md | 4 ++++ crypto/message.go | 2 +- go.mod | 2 +- helper/cleartext.go | 2 -- helper/cleartext_test.go | 12 +++--------- internal/common.go | 15 +++++++++------ 7 files changed, 19 insertions(+), 19 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 72182ea..3b31c7f 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -30,3 +30,4 @@ linters: - gci # Enforce blank lines check - nlreturn # Enforce blank lines for return statements - exhaustivestruct # Enforce structures to be fully filled on instantiation - terrible with openpgp configs + - paralleltest # detects missing usage of t.Parallel() method in your Go test \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ebc828..dda7148 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased +### Changed +- Improved canonicalization performance + ## [2.1.1] 2020-11-16 ### Changed - Session key decryption now considers multiple key packets diff --git a/crypto/message.go b/crypto/message.go index 94ec113..4baa87f 100644 --- a/crypto/message.go +++ b/crypto/message.go @@ -88,7 +88,7 @@ func NewPlainMessageFromFile(data []byte, filename string, time uint32) *PlainMe // ready for encryption, signature, or verification from an unencrypted string. func NewPlainMessageFromString(text string) *PlainMessage { return &PlainMessage{ - Data: []byte(strings.ReplaceAll(strings.ReplaceAll(text, "\r\n", "\n"), "\n", "\r\n")), + Data: []byte(internal.CanonicalizeAndTrim(text)), TextType: true, Filename: "", Time: uint32(GetUnixTime()), diff --git a/go.mod b/go.mod index e965839..84c2890 100644 --- a/go.mod +++ b/go.mod @@ -12,4 +12,4 @@ require ( replace golang.org/x/crypto => github.com/ProtonMail/crypto v0.0.0-20201112115411-41db4ea0dd1c -replace golang.org/x/mobile => github.com/zhj4478/mobile v0.0.0-20201014085805-7a2d68bf792f +replace golang.org/x/mobile => github.com/marinthiercelin/mobile v0.0.0-20201127122539-61ba718dc1d1 diff --git a/helper/cleartext.go b/helper/cleartext.go index 6d81c87..c318739 100644 --- a/helper/cleartext.go +++ b/helper/cleartext.go @@ -2,7 +2,6 @@ package helper import ( "github.com/ProtonMail/gopenpgp/v2/crypto" - "github.com/ProtonMail/gopenpgp/v2/internal" "github.com/pkg/errors" ) @@ -49,7 +48,6 @@ func VerifyCleartextMessageArmored(publicKey, armored string, verifyTime int64) // SignCleartextMessage signs text given a private keyring, canonicalizes and // trims the newlines, and returns the PGP-compliant special armoring. func SignCleartextMessage(keyRing *crypto.KeyRing, text string) (string, error) { - text = internal.TrimWhitespace(text) message := crypto.NewPlainMessageFromString(text) signature, err := keyRing.SignDetached(message) diff --git a/helper/cleartext_test.go b/helper/cleartext_test.go index 8452afb..6cf25b6 100644 --- a/helper/cleartext_test.go +++ b/helper/cleartext_test.go @@ -2,11 +2,11 @@ package helper import ( "regexp" - "strings" "testing" - "github.com/ProtonMail/gopenpgp/v2/crypto" "github.com/ProtonMail/gopenpgp/v2/internal" + + "github.com/ProtonMail/gopenpgp/v2/crypto" "github.com/stretchr/testify/assert" ) @@ -45,11 +45,5 @@ func TestSignClearText(t *testing.T) { if err != nil { t.Fatal("Cannot parse message:", err) } - assert.Exactly(t, canonicalizeAndTrim(inputPlainText), string(clearTextMessage.GetBinary())) -} - -func canonicalizeAndTrim(text string) string { - text = internal.TrimWhitespace(text) - text = strings.ReplaceAll(strings.ReplaceAll(text, "\r\n", "\n"), "\n", "\r\n") - return text + assert.Exactly(t, internal.CanonicalizeAndTrim(inputPlainText), string(clearTextMessage.GetBinary())) } diff --git a/internal/common.go b/internal/common.go index e2c69ad..9704cd0 100644 --- a/internal/common.go +++ b/internal/common.go @@ -2,16 +2,19 @@ package internal import ( - "regexp" + "strings" "github.com/ProtonMail/gopenpgp/v2/constants" ) -// TrimWhitespace removes whitespace from the end of each line of the input -// string. -func TrimWhitespace(input string) string { - var re = regexp.MustCompile(`(?m)[ \t]*$`) - return re.ReplaceAllString(input, "") +func CanonicalizeAndTrim(text string) string { + lines := strings.Split(text, "\n") + + for i := range lines { + lines[i] = strings.TrimRight(lines[i], " \t\r") + } + + return strings.Join(lines, "\r\n") } // CreationTimeOffset stores the amount of seconds that a signature may be