Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Golang check if string is valid path

Tags:

go

The Golang filepath module (https://golang.org/pkg/path/filepath/) contains a few functions for manipulating paths and os.Stat can be used to check if a file exists. Is there a way to check if a string actually forms a valid path at all (regardless of whether there's a file at that path or not)?

like image 848
Gregory Nisbet Avatar asked Feb 05 '16 19:02

Gregory Nisbet


People also ask

How do you validate a path in Golang?

Given a path, we have to check if a path is an absolute path in Golang. In the Go programming language, to check whether the given path is an absolute path or not – we use the IsAbs() function of the path/filepath package. The IsAbs() function true if the given path is an absolute path; false, otherwise.

How do you check the path is valid or not?

get(path) method returns a path. However if the path is not valid, then it throws InvalidPathException. For example Path. get("C://test.txt") will return true while Path.


1 Answers

This problem sounds very simple, but it is actually not. Here is two possible solutions that I found :

Solution 1 - Academic

The idea here is to check a given filepath based on rules.

Problems

  1. Operating system (UNIX / Windows)
  2. Filesystem
  3. Reserved keywords

Operating system

The first one is the easiest. Go provides various tools for OS-specific filenames/separators/...

Example in the os package:

const (
    PathSeparator     = '/' // OS-specific path separator
    PathListSeparator = ':' // OS-specific path list separator
)

Another one in the filepath package:

// VolumeName returns leading volume name.
// Given "C:\foo\bar" it returns "C:" on Windows.
// Given "\\host\share\foo" it returns "\\host\share".
// On other platforms it returns "".
func VolumeName(path string) string {
    return path[:volumeNameLen(path)]
}

Filesystem

Filesystems have different restrictions. The maximum length or the charset allowed may vary. Unfortunately, there is no way you can tell (not as far as I know at least) which filesystem(s) your path will traverse.

Reserved keywords

Have a blacklist of all reserved keywords for a given OS.

Implementation

For this solution, I would build a lexer/parser.

The tradeoff is that it would not guarantee 100% that a filepath is valid.

Solution 2 - Empirical

Attempt to create the file and delete it right after.

func IsValid(fp string) bool {
  // Check if file already exists
  if _, err := os.Stat(fp); err == nil {
    return true
  }

  // Attempt to create it
  var d []byte
  if err := ioutil.WriteFile(fp, d, 0644); err == nil {
    os.Remove(fp) // And delete it
    return true
  }

  return false
}

The main benefit of this solution is that it is straightforward and more accurate. If a file already exists or can be created at a given path, it means it is valid. However, this solution can also invalidate valid paths because of restricted access.

Summary

The first solution will be less accurate than the second one, even though more correct from a puristic point of view. The solution you should pick up depends on your need. Do you prefer false positives or false negatives? The first solution can give you false positives, while the second one false negatives.

like image 106
basgys Avatar answered Sep 21 '22 18:09

basgys