Browse Source

bug fixes

flashmob 6 years ago
parent
commit
e3f1d0a7da
5 changed files with 62 additions and 31 deletions
  1. 2 3
      api_test.go
  2. 1 1
      backends/gateway.go
  3. 1 1
      backends/s_mime.go
  4. 16 8
      mail/mime/mime.go
  5. 42 18
      mail/mime/mime_test.go

+ 2 - 3
api_test.go

@@ -11,7 +11,6 @@ import (
 	"io/ioutil"
 	"io/ioutil"
 	"net"
 	"net"
 	"os"
 	"os"
-	"runtime/pprof"
 	"strings"
 	"strings"
 	"testing"
 	"testing"
 	"time"
 	"time"
@@ -928,8 +927,8 @@ func TestStreamMimeProcessor(t *testing.T) {
 		//		*moo = *moo + 6
 		//		*moo = *moo + 6
 
 
 		// for debugging deadlocks
 		// for debugging deadlocks
-		pprof.Lookup("goroutine").WriteTo(os.Stdout, 1)
-		os.Exit(1)
+		//pprof.Lookup("goroutine").WriteTo(os.Stdout, 1)
+		//os.Exit(1)
 	}()
 	}()
 
 
 	// change \n to \r\n
 	// change \n to \r\n

+ 1 - 1
backends/gateway.go

@@ -603,7 +603,7 @@ func (gw *BackendGateway) workDispatcher(
 				if err == nil {
 				if err == nil {
 					var buf []byte
 					var buf []byte
 					buf = make([]byte, 1024*4)
 					buf = make([]byte, 1024*4)
-					buf = make([]byte, 256)
+					buf = make([]byte, 210)
 					if msg.e.Values["size"], err = io.CopyBuffer(stream, msg.r, buf); err != nil {
 					if msg.e.Values["size"], err = io.CopyBuffer(stream, msg.r, buf); err != nil {
 						Log().WithError(err).Error("stream writing failed")
 						Log().WithError(err).Error("stream writing failed")
 					}
 					}

+ 1 - 1
backends/s_mime.go

@@ -44,7 +44,7 @@ func StreamMimeAnalyzer() *StreamDecorator {
 
 
 			Svc.AddShutdowner(ShutdownWith(func() error {
 			Svc.AddShutdowner(ShutdownWith(func() error {
 				fmt.Println("shutdownewr")
 				fmt.Println("shutdownewr")
-				_ = parser.Close()
+				//_ = parser.Close()
 				return nil
 				return nil
 			}))
 			}))
 
 

+ 16 - 8
mail/mime/mime.go

@@ -161,11 +161,13 @@ func (p *Parser) next() byte {
 			return 0
 			return 0
 		}
 		}
 	}
 	}
-
-	// go to the next byte
+	if p.pos > -1 || p.msgPos != 0 {
+		// dont incr on first call to next()
+		p.msgPos++
+	}
 	p.pos++
 	p.pos++
 	p.ch = p.buf[p.pos]
 	p.ch = p.buf[p.pos]
-	p.msgPos++
+
 	if p.ch == '\n' {
 	if p.ch == '\n' {
 		p.msgLine++
 		p.msgLine++
 	}
 	}
@@ -240,7 +242,7 @@ func (p *Parser) boundary(contentBoundary string) (end bool, err error) {
 	if len(contentBoundary) < 1 {
 	if len(contentBoundary) < 1 {
 		err = errors.New("content boundary too short")
 		err = errors.New("content boundary too short")
 	}
 	}
-	boundary := doubleDash + contentBoundary
+	boundary := "\n" + doubleDash + contentBoundary
 	p.boundaryMatched = 0
 	p.boundaryMatched = 0
 	for {
 	for {
 		if i := bytes.Index(p.buf[p.pos:], []byte(boundary)); i > -1 {
 		if i := bytes.Index(p.buf[p.pos:], []byte(boundary)); i > -1 {
@@ -250,8 +252,9 @@ func (p *Parser) boundary(contentBoundary string) (end bool, err error) {
 			// will wait until we get a new buffer
 			// will wait until we get a new buffer
 
 
 			p.skip(i)
 			p.skip(i)
-			p.lastBoundaryPos = p.msgPos - 1 // - uint(len(boundary))
+			p.lastBoundaryPos = p.msgPos // -1 - uint(len(boundary))
 			p.skip(len(boundary))
 			p.skip(len(boundary))
+
 			if end, err = p.boundaryEnd(); err != nil {
 			if end, err = p.boundaryEnd(); err != nil {
 				return
 				return
 			}
 			}
@@ -280,7 +283,9 @@ func (p *Parser) boundary(contentBoundary string) (end bool, err error) {
 					p.boundaryMatched = 0
 					p.boundaryMatched = 0
 				}
 				}
 			}
 			}
-			p.skip(len(p.buf))
+
+			p.skip(len(p.buf) - p.pos) // discard the remaining data
+
 			if p.ch == 0 {
 			if p.ch == 0 {
 				return false, io.EOF
 				return false, io.EOF
 			} else if p.boundaryMatched > 0 {
 			} else if p.boundaryMatched > 0 {
@@ -293,7 +298,7 @@ func (p *Parser) boundary(contentBoundary string) (end bool, err error) {
 					// advance the pointer
 					// advance the pointer
 					p.skip(len(boundary) - p.boundaryMatched)
 					p.skip(len(boundary) - p.boundaryMatched)
 
 
-					p.lastBoundaryPos = p.msgPos - uint(len(boundary)) - 1
+					p.lastBoundaryPos = p.msgPos - uint(len(boundary)) // -1
 					end, err = p.boundaryEnd()
 					end, err = p.boundaryEnd()
 					if err != nil {
 					if err != nil {
 						return
 						return
@@ -781,9 +786,9 @@ func (p *Parser) mime(parent *Part, depth string) (err error) {
 			err = NotMime
 			err = NotMime
 			return
 			return
 		}
 		}
-
 		// after we return from the lower branches (if there were any)
 		// after we return from the lower branches (if there were any)
 		// we walk each of the siblings of the parent
 		// we walk each of the siblings of the parent
+
 		if end, bErr := p.boundary(parent.ContentBoundary); bErr != nil {
 		if end, bErr := p.boundary(parent.ContentBoundary); bErr != nil {
 			part.EndingPosBody = p.lastBoundaryPos
 			part.EndingPosBody = p.lastBoundaryPos
 			return bErr
 			return bErr
@@ -795,6 +800,7 @@ func (p *Parser) mime(parent *Part, depth string) (err error) {
 		part.EndingPosBody = p.lastBoundaryPos
 		part.EndingPosBody = p.lastBoundaryPos
 		count++
 		count++
 	}
 	}
+
 	return
 	return
 }
 }
 
 
@@ -804,6 +810,7 @@ func (p *Parser) reset() {
 	p.msgPos = 0
 	p.msgPos = 0
 	p.msgLine = 0
 	p.msgLine = 0
 	p.count = 0
 	p.count = 0
+	p.ch = 0
 }
 }
 
 
 // Close tells the MIME Parser there's no more data & waits for it to return a result
 // Close tells the MIME Parser there's no more data & waits for it to return a result
@@ -843,6 +850,7 @@ func (p *Parser) Parse(buf []byte) error {
 
 
 	if p.count == 0 {
 	if p.count == 0 {
 		//open
 		//open
+
 		go func() {
 		go func() {
 			p.next()
 			p.next()
 			err := p.mime(nil, "")
 			err := p.mime(nil, "")

+ 42 - 18
mail/mime/mime_test.go

@@ -23,6 +23,11 @@ func TestInject(t *testing.T) {
 	p.inject([]byte("abcd"), []byte("efgh"), []byte("ijkl"))
 	p.inject([]byte("abcd"), []byte("efgh"), []byte("ijkl"))
 	for i := 0; i < 12; i++ {
 	for i := 0; i < 12; i++ {
 		b.WriteByte(p.ch)
 		b.WriteByte(p.ch)
+		if p.pos == 3 && p.msgPos < 4 {
+			if c := p.peek(); c != 101 {
+				t.Error("next() expecting e, got:", string(c))
+			}
+		}
 		p.next()
 		p.next()
 		if p.ch == 0 {
 		if p.ch == 0 {
 			break
 			break
@@ -129,7 +134,7 @@ func TestBoundary(t *testing.T) {
 	p.inject([]byte(test))
 	p.inject([]byte(test))
 
 
 	_, err = p.boundary(part.ContentBoundary)
 	_, err = p.boundary(part.ContentBoundary)
-	if err != nil {
+	if err != nil && err != io.EOF {
 		t.Error(err)
 		t.Error(err)
 	}
 	}
 	fmt.Println(string(test[:p.lastBoundaryPos]))
 	fmt.Println(string(test[:p.lastBoundaryPos]))
@@ -137,34 +142,53 @@ func TestBoundary(t *testing.T) {
 	// at the end (with the -- postfix)
 	// at the end (with the -- postfix)
 	p.inject([]byte("The quick brown fox jumped over the lazy dog---wololo---\n"))
 	p.inject([]byte("The quick brown fox jumped over the lazy dog---wololo---\n"))
 	_, err = p.boundary(part.ContentBoundary)
 	_, err = p.boundary(part.ContentBoundary)
-	if err != nil {
+	if err != nil && err != io.EOF {
 		t.Error(err)
 		t.Error(err)
 	}
 	}
 
 
-	for c := p.next(); c != 0; c = p.next() {
-	} // drain
+	//for c := p.next(); c != 0; c = p.next() {
+	//} // drain
+
+	// the boundary with an additional buffer in between
+	p.inject([]byte("The quick brown fox jumped over the lazy dog"),
+		[]byte("this is the middle"),
+		[]byte("and thats the end---wololo---\n"))
+
+	_, err = p.boundary(part.ContentBoundary)
+	if err != nil && err != io.EOF {
+		t.Error(err)
+	}
+
+}
 
 
+// todo: make sure next() advances properly
+func TestBoundarySplit(t *testing.T) {
+	p = NewMimeParser()
+	var err error
+	part := newPart()
+
+	part.ContentBoundary = "-wololo-"
 	// boundary is split over multiple slices
 	// boundary is split over multiple slices
 	p.inject(
 	p.inject(
 		[]byte("The quick brown fox jumped ov---wolo"),
 		[]byte("The quick brown fox jumped ov---wolo"),
 		[]byte("lo---\ner the lazy dog"))
 		[]byte("lo---\ner the lazy dog"))
 	_, err = p.boundary(part.ContentBoundary)
 	_, err = p.boundary(part.ContentBoundary)
-	if err != nil {
+	if err != nil && err != io.EOF {
 		t.Error(err)
 		t.Error(err)
 	}
 	}
-	all := []byte("The quick brown fox jumped ov---wololo---\ner the lazy dog")
-	//all[p.lastBoundaryPos] = 'X'
-	fmt.Println(string(all[:p.lastBoundaryPos]))
-	for c := p.next(); c != 0; c = p.next() {
-	} // drain
-	// the boundary with an additional buffer in between
-	p.inject([]byte("The quick brown fox jumped over the lazy dog"),
-		[]byte("this is the middle"),
-		[]byte("and thats the end---wololo---\n"))
 
 
+	fmt.Println(string([]byte("The quick brown fox jumped ov---wolo")[:p.lastBoundaryPos]))
+
+	// boundary has a space, pointer advanced before, and is split over multiple slices
+	part.ContentBoundary = "XXXXboundary text" // 17 chars
+	p.inject(
+		[]byte("The quick brown fox jumped ov--X"),
+		[]byte("XXXboundary text\ner the lazy dog"))
+	p.next() // here the pointer is advanced before the boundary is searched
 	_, err = p.boundary(part.ContentBoundary)
 	_, err = p.boundary(part.ContentBoundary)
-	if err != nil {
+	if err != nil && err != io.EOF {
 		t.Error(err)
 		t.Error(err)
+		return
 	}
 	}
 
 
 }
 }
@@ -416,7 +440,7 @@ TmV4dFBhcnRfMDAwX0FFNkJfNzI1RTA5QUYuODhCN0Y5MzQtLQ0K
 
 
 func TestNestedEmail(t *testing.T) {
 func TestNestedEmail(t *testing.T) {
 	p = NewMimeParser()
 	p = NewMimeParser()
-	email = email3
+	email = email
 	p.inject([]byte(email))
 	p.inject([]byte(email))
 
 
 	go func() {
 	go func() {
@@ -440,8 +464,8 @@ func TestNestedEmail(t *testing.T) {
 	}
 	}
 	fmt.Print(email)
 	fmt.Print(email)
 	//fmt.Println(strings.Index(email, "--D7F------------D7FD5A0B8AB9C65CCDBFA872--"))
 	//fmt.Println(strings.Index(email, "--D7F------------D7FD5A0B8AB9C65CCDBFA872--"))
-
-	//fmt.Println(email[p.parts[1].startingPosBody:p.parts[1].endingPosBody])
+	i := 0
+	fmt.Println("[" + email[p.Parts[i].StartingPosBody:p.Parts[i].EndingPosBody] + "]")
 	//i := 2
 	//i := 2
 	//fmt.Println("**********{" + email[p.parts[i].startingPosBody:p.parts[i].endingPosBody] + "}**********")
 	//fmt.Println("**********{" + email[p.parts[i].startingPosBody:p.parts[i].endingPosBody] + "}**********")
 }
 }