

filepath.Ext Notes
source link: https://parsiya.net/blog/2018-11-10-filepath.ext-notes/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Nov 10, 2018 - 3 minute read - Comments - Go
filepath.Ext Notes
The filepath package has some functions for processing paths and filenames. I am using it extensively in a current project. You can do cool stuff with it, like traversing a path recursively with filepath.Walk.
filepath.Ext returns the extension of a filename (or path). It returns whatever is after the last dot. It has some gotchas that might have security implications.
Code is at: https://github.com/parsiya/Parsia-Code/tree/master/filepath-ext
Source
https://golang.org/src/path/filepath/path.go?s=6131:6159#L207
// Ext returns the file name extension used by path.
// The extension is the suffix beginning at the final dot
// in the final element of path; it is empty if there is
// no dot.
func Ext(path string) string {
for i := len(path) - 1; i >= 0 && !os.IsPathSeparator(path[i]); i-- {
if path[i] == '.' {
return path[i:]
}
}
return ""
}
Example
To demonstrate the tips, we are going to create a simple example. Let's assume we have a file hosting service. We have created a blacklist of banned extensions. It checks the files by extension. This is not really a good way to do this:
- It's better to default to deny and then use a whitelist.
- Detecting file types by extension is easily bypassed by changing the extension. However, this might render some attacks invalid. Consider an attack where a user downloads a file, if the attacker has been forced to rename the file from
exe
totxt
or another random extension, the user needs to manually rename it back and execute it.
But let's use it for demonstrating our points. This is the blacklist function:
// Blacklist returns true if a file is one of the banned types by checking its extension.
func Blacklist(filename string) bool {
if filepath.Ext(filename) == ".exe" {
return false
}
return true
}
Ext Keeps the Case of Input
The input's letter case does not change. Everything is just passed through. Consider the following code (case.go
):
package main
import (
"fmt"
"path/filepath"
)
func main() {
fmt.Println("filepath.Ext(\"whatever.txt\"):", filepath.Ext("whatever.txt"))
// filepath.Ext("whatever.txt"): .txt
fmt.Println("filepath.Ext(\"whatever.TXT\"):", filepath.Ext("whatever.TXT"))
// filepath.Ext("whatever.TXT"): .TXT
fmt.Println("filepath.Ext(\"whatever.Txt\"):", filepath.Ext("whatever.Txt"))
// filepath.Ext("whatever.Txt"): .Txt
}
To bypass the blacklist, we can just change the case case_blacklist.go
:
func main() {
fmt.Println("Blacklist(\"whatever.exe\"):", Blacklist("whatever.exe"))
// true
fmt.Println("Blacklist(\"whatever.ExE\"):", Blacklist("whatever.ExE"))
// false
}
Ext Returns the dot with the Extension
In our mind, the extension of a file is just the letters after the dot. It does not include the dot. However, Ext returns the dot. This is really unintuitive and has caught me off guard a few times.
package main
import (
"fmt"
"path/filepath"
)
func main() {
fmt.Println("Blacklist(\"whatever.exe\"):", Blacklist("whatever.exe"))
// true
}
// Blacklist returns true if a file is one of the banned types by checking its extension.
func Blacklist(filename string) bool {
// Developers did not expect the dot to be part of the output.
if filepath.Ext(filename) == "exe" {
return false
}
return true
}
This blacklist is useless, the condition is never true.
Returns an Empty String if Input has no Dots
This is mentioned in the docs but aI did not expect it.
Recommend
-
45
Expand incomplete file paths in bash. For example: /u/s/app<Tab> will be expanded into /usr/share/applications Read more: Blog post: https://potyarkin.ml/posts/2018/enhanced-file-path-complet...
-
66
README.md English | 中文 MySQL ORM User Guide Catalogue Instruction
-
25
After 12 years, it was time. We went back to the drawing board and completely re-engineered an entirely new engine and runtime to support ASP.NET Core. Performance and automation were key goals and the team levera...
-
18
libs/ext.sf.select2.tokens.jsLoading...Content licensed under Creative Commons Attribution-ShareAlike 3.0 (CC-BY-SA) unless otherwise noted; code li...
-
9
Merged turnip: fix VK_EXT_extended_dynamic_state CTS failures due to LRZ Detached...
-
6
Copy link Contributor tywhang commented...
-
8
Copy link Member eileencodes
-
4
Rails 7 adds support for setting the schema dump filepath in the database config Mar 9, 2022 , by Swaathi Kakarla 1 minute...
-
7
How to recover filepath from a given directory in C advertisements I'm looking for an efficient way to convert...
-
4
Mryqu's Notes GoLang语言filepath包Clean函数功能如下:Replace multiple Separator elements with a sing...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK