Browse Source

restore: clean up leftover and invalid chars (#6875)

Joe Chen 3 years ago
parent
commit
f37cd9672c
2 changed files with 24 additions and 13 deletions
  1. 19 12
      internal/cmd/restore.go
  2. 5 1
      internal/db/backup.go

+ 19 - 12
internal/cmd/restore.go

@@ -11,13 +11,13 @@ import (
 
 	"github.com/pkg/errors"
 	"github.com/unknwon/cae/zip"
-	"github.com/unknwon/com"
 	"github.com/urfave/cli"
 	"gopkg.in/ini.v1"
 	log "unknwon.dev/clog/v2"
 
 	"gogs.io/gogs/internal/conf"
 	"gogs.io/gogs/internal/db"
+	"gogs.io/gogs/internal/osutil"
 	"gogs.io/gogs/internal/semverutil"
 )
 
@@ -49,20 +49,27 @@ func runRestore(c *cli.Context) error {
 	zip.Verbose = c.Bool("verbose")
 
 	tmpDir := c.String("tempdir")
-	if !com.IsExist(tmpDir) {
+	if !osutil.IsDir(tmpDir) {
 		log.Fatal("'--tempdir' does not exist: %s", tmpDir)
 	}
+	archivePath := path.Join(tmpDir, archiveRootDir)
 
-	log.Info("Restore backup from: %s", c.String("from"))
-	if err := zip.ExtractTo(c.String("from"), tmpDir); err != nil {
-		log.Fatal("Failed to extract backup archive: %v", err)
+	// Make sure there was no leftover and also clean up afterwards
+	err := os.RemoveAll(archivePath)
+	if err != nil {
+		log.Fatal("Failed to clean up previous leftover in %q: %v", archivePath, err)
 	}
-	archivePath := path.Join(tmpDir, archiveRootDir)
 	defer func() { _ = os.RemoveAll(archivePath) }()
 
+	log.Info("Restoring backup from: %s", c.String("from"))
+	err = zip.ExtractTo(c.String("from"), tmpDir)
+	if err != nil {
+		log.Fatal("Failed to extract backup archive: %v", err)
+	}
+
 	// Check backup version
 	metaFile := filepath.Join(archivePath, "metadata.ini")
-	if !com.IsExist(metaFile) {
+	if !osutil.IsFile(metaFile) {
 		log.Fatal("File 'metadata.ini' is missing")
 	}
 	metadata, err := ini.Load(metaFile)
@@ -88,7 +95,7 @@ func runRestore(c *cli.Context) error {
 	var customConf string
 	if c.IsSet("config") {
 		customConf = c.String("config")
-	} else if !com.IsExist(configFile) {
+	} else if !osutil.IsFile(configFile) {
 		log.Fatal("'--config' is not specified and custom config file is not found in backup")
 	} else {
 		customConf = configFile
@@ -113,7 +120,7 @@ func runRestore(c *cli.Context) error {
 
 	// Custom files
 	if !c.Bool("database-only") {
-		if com.IsExist(conf.CustomDir()) {
+		if osutil.IsDir(conf.CustomDir()) {
 			if err = os.Rename(conf.CustomDir(), conf.CustomDir()+".bak"); err != nil {
 				log.Fatal("Failed to backup current 'custom': %v", err)
 			}
@@ -129,12 +136,12 @@ func runRestore(c *cli.Context) error {
 		for _, dir := range []string{"attachments", "avatars", "repo-avatars"} {
 			// Skip if backup archive does not have corresponding data
 			srcPath := filepath.Join(archivePath, "data", dir)
-			if !com.IsDir(srcPath) {
+			if !osutil.IsDir(srcPath) {
 				continue
 			}
 
 			dirPath := filepath.Join(conf.Server.AppDataPath, dir)
-			if com.IsExist(dirPath) {
+			if osutil.IsDir(dirPath) {
 				if err = os.Rename(dirPath, dirPath+".bak"); err != nil {
 					log.Fatal("Failed to backup current 'data': %v", err)
 				}
@@ -147,7 +154,7 @@ func runRestore(c *cli.Context) error {
 
 	// Repositories
 	reposPath := filepath.Join(archivePath, "repositories.zip")
-	if !c.Bool("exclude-repos") && !c.Bool("database-only") && com.IsExist(reposPath) {
+	if !c.Bool("exclude-repos") && !c.Bool("database-only") && osutil.IsDir(reposPath) {
 		if err := zip.ExtractTo(reposPath, filepath.Dir(conf.Repository.Root)); err != nil {
 			log.Fatal("Failed to extract 'repositories.zip': %v", err)
 		}

+ 5 - 1
internal/db/backup.go

@@ -2,6 +2,7 @@ package db
 
 import (
 	"bufio"
+	"bytes"
 	"fmt"
 	"io"
 	"os"
@@ -176,8 +177,11 @@ func importTable(db *gorm.DB, table interface{}, r io.Reader) error {
 
 	scanner := bufio.NewScanner(r)
 	for scanner.Scan() {
+		// PostgreSQL does not like the null characters (U+0000)
+		cleaned := bytes.ReplaceAll(scanner.Bytes(), []byte("\\u0000"), []byte(""))
+
 		elem := reflect.New(reflect.TypeOf(table).Elem()).Interface()
-		err = jsoniter.Unmarshal(scanner.Bytes(), elem)
+		err = jsoniter.Unmarshal(cleaned, elem)
 		if err != nil {
 			return errors.Wrap(err, "unmarshal JSON to struct")
 		}