hugo

Fork of github.com/gohugoio/hugo with reverse pagination support

git clone git://git.shimmy1996.com/hugo.git

nosymlink_test.go (4257B)

    1 // Copyright 2019 The Hugo Authors. All rights reserved.
    2 //
    3 // Licensed under the Apache License, Version 2.0 (the "License");
    4 // you may not use this file except in compliance with the License.
    5 // You may obtain a copy of the License at
    6 // http://www.apache.org/licenses/LICENSE-2.0
    7 //
    8 // Unless required by applicable law or agreed to in writing, software
    9 // distributed under the License is distributed on an "AS IS" BASIS,
   10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   11 // See the License for the specific language governing permissions and
   12 // limitations under the License.
   13 
   14 package hugofs
   15 
   16 import (
   17 	"os"
   18 	"path/filepath"
   19 	"testing"
   20 
   21 	"github.com/gohugoio/hugo/common/loggers"
   22 
   23 	"github.com/gohugoio/hugo/htesting"
   24 
   25 	"github.com/spf13/afero"
   26 
   27 	qt "github.com/frankban/quicktest"
   28 )
   29 
   30 func prepareSymlinks(t *testing.T) (string, func()) {
   31 	c := qt.New(t)
   32 
   33 	workDir, clean, err := htesting.CreateTempDir(Os, "hugo-symlink-test")
   34 	c.Assert(err, qt.IsNil)
   35 	wd, _ := os.Getwd()
   36 
   37 	blogDir := filepath.Join(workDir, "blog")
   38 	blogSubDir := filepath.Join(blogDir, "sub")
   39 	c.Assert(os.MkdirAll(blogSubDir, 0777), qt.IsNil)
   40 	blogFile1 := filepath.Join(blogDir, "a.txt")
   41 	blogFile2 := filepath.Join(blogSubDir, "b.txt")
   42 	afero.WriteFile(Os, filepath.Join(blogFile1), []byte("content1"), 0777)
   43 	afero.WriteFile(Os, filepath.Join(blogFile2), []byte("content2"), 0777)
   44 	os.Chdir(workDir)
   45 	c.Assert(os.Symlink("blog", "symlinkdedir"), qt.IsNil)
   46 	os.Chdir(blogDir)
   47 	c.Assert(os.Symlink("sub", "symsub"), qt.IsNil)
   48 	c.Assert(os.Symlink("a.txt", "symlinkdedfile.txt"), qt.IsNil)
   49 
   50 	return workDir, func() {
   51 		clean()
   52 		os.Chdir(wd)
   53 	}
   54 }
   55 
   56 func TestNoSymlinkFs(t *testing.T) {
   57 	if skipSymlink() {
   58 		t.Skip("Skip; os.Symlink needs administrator rights on Windows")
   59 	}
   60 	c := qt.New(t)
   61 	workDir, clean := prepareSymlinks(t)
   62 	defer clean()
   63 
   64 	blogDir := filepath.Join(workDir, "blog")
   65 	blogFile1 := filepath.Join(blogDir, "a.txt")
   66 
   67 	logger := loggers.NewWarningLogger()
   68 
   69 	for _, bfs := range []afero.Fs{NewBaseFileDecorator(Os), Os} {
   70 		for _, allowFiles := range []bool{false, true} {
   71 			logger.LogCounters().WarnCounter.Reset()
   72 			fs := NewNoSymlinkFs(bfs, logger, allowFiles)
   73 			ls := fs.(afero.Lstater)
   74 			symlinkedDir := filepath.Join(workDir, "symlinkdedir")
   75 			symlinkedFilename := "symlinkdedfile.txt"
   76 			symlinkedFile := filepath.Join(blogDir, symlinkedFilename)
   77 
   78 			assertFileErr := func(err error) {
   79 				if allowFiles {
   80 					c.Assert(err, qt.IsNil)
   81 				} else {
   82 					c.Assert(err, qt.Equals, ErrPermissionSymlink)
   83 				}
   84 			}
   85 
   86 			assertFileStat := func(name string, fi os.FileInfo, err error) {
   87 				t.Helper()
   88 				assertFileErr(err)
   89 				if err == nil {
   90 					c.Assert(fi, qt.Not(qt.IsNil))
   91 					c.Assert(fi.Name(), qt.Equals, name)
   92 				}
   93 			}
   94 
   95 			// Check Stat and Lstat
   96 			for _, stat := range []func(name string) (os.FileInfo, error){
   97 				func(name string) (os.FileInfo, error) {
   98 					return fs.Stat(name)
   99 				},
  100 				func(name string) (os.FileInfo, error) {
  101 					fi, _, err := ls.LstatIfPossible(name)
  102 					return fi, err
  103 				},
  104 			} {
  105 				_, err := stat(symlinkedDir)
  106 				c.Assert(err, qt.Equals, ErrPermissionSymlink)
  107 				fi, err := stat(symlinkedFile)
  108 				assertFileStat(symlinkedFilename, fi, err)
  109 
  110 				fi, err = stat(filepath.Join(workDir, "blog"))
  111 				c.Assert(err, qt.IsNil)
  112 				c.Assert(fi, qt.Not(qt.IsNil))
  113 
  114 				fi, err = stat(blogFile1)
  115 				c.Assert(err, qt.IsNil)
  116 				c.Assert(fi, qt.Not(qt.IsNil))
  117 			}
  118 
  119 			// Check Open
  120 			_, err := fs.Open(symlinkedDir)
  121 			c.Assert(err, qt.Equals, ErrPermissionSymlink)
  122 			_, err = fs.OpenFile(symlinkedDir, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0666)
  123 			c.Assert(err, qt.Equals, ErrPermissionSymlink)
  124 			_, err = fs.OpenFile(symlinkedFile, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0666)
  125 			assertFileErr(err)
  126 			_, err = fs.Open(symlinkedFile)
  127 			assertFileErr(err)
  128 			f, err := fs.Open(blogDir)
  129 			c.Assert(err, qt.IsNil)
  130 			f.Close()
  131 			f, err = fs.Open(blogFile1)
  132 			c.Assert(err, qt.IsNil)
  133 			f.Close()
  134 
  135 			// Check readdir
  136 			f, err = fs.Open(workDir)
  137 			c.Assert(err, qt.IsNil)
  138 			// There is at least one unsupported symlink inside workDir
  139 			_, err = f.Readdir(-1)
  140 			c.Assert(err, qt.IsNil)
  141 			f.Close()
  142 			c.Assert(logger.LogCounters().WarnCounter.Count(), qt.Equals, uint64(1))
  143 
  144 		}
  145 	}
  146 }