diff --git a/server/app/import.go b/server/app/import.go index 7ea99cd87..2852c0e3e 100644 --- a/server/app/import.go +++ b/server/app/import.go @@ -20,12 +20,14 @@ import ( ) const ( - archiveVersion = 2 - legacyFileBegin = "{\"version\":1" + archiveVersion = 2 + legacyFileBegin = "{\"version\":1" + importMaxFileSize = 1024 * 1024 * 70 ) var ( - errBlockIsNotABoard = errors.New("block is not a board") + errBlockIsNotABoard = errors.New("block is not a board") + errSizeLimitExceeded = errors.New("size limit exceeded") ) // ImportArchive imports an archive containing zero or more boards, plus all @@ -153,7 +155,8 @@ func (a *App) ImportBoardJSONL(r io.Reader, opt model.ImportArchiveOptions) (*mo Blocks: make([]*model.Block, 0, 10), Boards: make([]*model.Board, 0, 10), } - lineReader := bufio.NewReader(r) + lineReader := &io.LimitedReader{R: r, N: importMaxFileSize + 1} + scanner := bufio.NewScanner(lineReader) userID := opt.ModifiedBy if userID == model.SingleUser { @@ -165,8 +168,12 @@ func (a *App) ImportBoardJSONL(r io.Reader, opt model.ImportArchiveOptions) (*mo lineNum := 1 firstLine := true - for { - line, errRead := readLine(lineReader) + for scanner.Scan() { + if lineReader.N <= 0 { + return nil, fmt.Errorf("error parsing archive line %d: %w", lineNum, errSizeLimitExceeded) + } + + line := bytes.TrimSpace(scanner.Bytes()) if len(line) != 0 { var skip bool if firstLine { @@ -233,14 +240,10 @@ func (a *App) ImportBoardJSONL(r io.Reader, opt model.ImportArchiveOptions) (*mo firstLine = false } } + } - if errRead != nil { - if errors.Is(errRead, io.EOF) { - break - } - return nil, fmt.Errorf("error reading archive line %d: %w", lineNum, errRead) - } - lineNum++ + if errRead := scanner.Err(); errRead != nil { + return nil, fmt.Errorf("error reading archive line %d: %w", lineNum, errRead) } // loop to remove the people how are not part of the team and system @@ -462,9 +465,3 @@ func parseVersionFile(r io.Reader) (int, error) { } return header.Version, nil } - -func readLine(r *bufio.Reader) ([]byte, error) { - line, err := r.ReadBytes('\n') - line = bytes.TrimSpace(line) - return line, err -}