]> Cypherpunks repositories - gostls13.git/commitdiff
godoc: fix zip file directory lookup
authorRobert Griesemer <gri@golang.org>
Wed, 20 Jul 2011 23:22:13 +0000 (16:22 -0700)
committerRobert Griesemer <gri@golang.org>
Wed, 20 Jul 2011 23:22:13 +0000 (16:22 -0700)
Also: remove left-over println calls.

R=bradfitz
CC=golang-dev
https://golang.org/cl/4807042

src/cmd/godoc/httpzip.go
src/cmd/godoc/zip.go

index 97d856943050a4a3b68ace0a53aa00132e56f2c1..1b8bc87e8a593dcd798053342f29dd81bc3350ba 100644 (file)
@@ -61,7 +61,6 @@ func (f *httpZipFile) Stat() (*os.FileInfo, os.Error) {
 }
 
 func (f *httpZipFile) Readdir(count int) ([]os.FileInfo, os.Error) {
-       println("Readdir", f.info.Name)
        if f.info.IsRegular() {
                return nil, fmt.Errorf("Readdir called for regular file: %s", f.info.Name)
        }
@@ -134,14 +133,15 @@ type httpZipFS struct {
 }
 
 func (fs *httpZipFS) Open(abspath string) (http.File, os.Error) {
-       name := path.Join(fs.root, abspath)
-       index := fs.list.lookup(name)
+       name := path.Join(fs.root, abspath) // name is clean
+       index, exact := fs.list.lookup(name)
        if index < 0 {
                return nil, fmt.Errorf("file not found: %s", abspath)
        }
 
-       if f := fs.list[index]; f.Name == name {
+       if exact {
                // exact match found - must be a file
+               f := fs.list[index]
                rc, err := f.Open()
                if err != nil {
                        return nil, err
@@ -159,7 +159,6 @@ func (fs *httpZipFS) Open(abspath string) (http.File, os.Error) {
        }
 
        // not an exact match - must be a directory
-       println("opened directory", abspath, len(fs.list[index:]))
        return &httpZipFile{
                os.FileInfo{
                        Name: abspath,
index eac6992387be6543f85d5e22d5db8fecf2b500b0..28789f8a0b36ccc2d8e9ee5ad32257c9a67e0cac 100644 (file)
@@ -73,22 +73,23 @@ func (fs *zipFS) Close() os.Error {
 }
 
 func zipPath(name string) string {
+       name = path.Clean(name)
        if !path.IsAbs(name) {
                panic(fmt.Sprintf("stat: not an absolute path: %s", name))
        }
-       return name[1:] // strip '/'
+       return name[1:] // strip leading '/'
 }
 
 func (fs *zipFS) stat(abspath string) (int, zipFI, os.Error) {
-       i := fs.list.lookup(abspath)
+       i, exact := fs.list.lookup(abspath)
        if i < 0 {
                return -1, zipFI{}, fmt.Errorf("file not found: %s", abspath)
        }
+       _, name := path.Split(abspath)
        var file *zip.File
-       if abspath == fs.list[i].Name {
+       if exact {
                file = fs.list[i] // exact match found - must be a file
        }
-       _, name := path.Split(abspath)
        return i, zipFI{name, file}, nil
 }
 
@@ -173,17 +174,29 @@ func (z zipList) Len() int           { return len(z) }
 func (z zipList) Less(i, j int) bool { return z[i].Name < z[j].Name }
 func (z zipList) Swap(i, j int)      { z[i], z[j] = z[j], z[i] }
 
-// lookup returns the first index in the zipList
-// of a path equal to name or beginning with name/.
-func (z zipList) lookup(name string) int {
+// lookup returns the smallest index of an entry with an exact match
+// for name, or an inexact match starting with name/. If there is no
+// such entry, the result is -1, false.
+func (z zipList) lookup(name string) (index int, exact bool) {
+       // look for exact match first (name comes before name/ in z)
        i := sort.Search(len(z), func(i int) bool {
                return name <= z[i].Name
        })
-       if i >= 0 {
-               iname := z[i].Name
-               if strings.HasPrefix(iname, name) && (len(name) == len(iname) || iname[len(name)] == '/') {
-                       return i
-               }
+       if i < 0 {
+               return -1, false
+       }
+       if z[i].Name == name {
+               return i, true
+       }
+
+       // look for inexact match (must be in z[i:], if present)
+       z = z[i:]
+       name += "/"
+       j := sort.Search(len(z), func(i int) bool {
+               return name <= z[i].Name
+       })
+       if j < 0 {
+               return -1, false
        }
-       return -1 // no match
+       return i + j, false
 }