Skip to content

Commit

Permalink
Merge pull request #51 from ooni/merged-main
Browse files Browse the repository at this point in the history
chore: sync up with go1.20.11
  • Loading branch information
bassosimone authored Nov 22, 2023
2 parents 7b3c08c + 9fb1889 commit e944bc2
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 35 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,8 @@ patches](#patches) still hold;
- [ ] make sure the codebase does not assume `*tls.Conn` *anywhere* (`git grep -n '\*tls\.Conn'`)
and otherwise replace `*tls.Conn` with `TLSConn`;

- [ ] make sure the codebase does not call `tls.Client` *anywhere* (`git grep -n 'tls\.Client'`)
and otherwise replace `tls.Client` with `TLSClientFactory`;
- [ ] make sure the codebase does not call `tls.Client` *anywhere* except for `tlsconn.go`
(`git grep -n 'tls\.Client'`) and otherwise replace `tls.Client` with `TLSClientFactory`;

- [ ] ensure `go build -v ./...` still works;

Expand Down
2 changes: 1 addition & 1 deletion UPSTREAM
Original file line number Diff line number Diff line change
@@ -1 +1 @@
go1.20.10
go1.20.11
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ module github.com/ooni/oohttp

go 1.20

require golang.org/x/net v0.15.0
require golang.org/x/net v0.18.0

require golang.org/x/text v0.13.0 // indirect
require golang.org/x/text v0.14.0 // indirect
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8=
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg=
golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
1 change: 1 addition & 0 deletions h2_bundle.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

98 changes: 72 additions & 26 deletions internal/safefilepath/path_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,10 @@ func fromFS(path string) (string, error) {
for p := path; p != ""; {
// Find the next path element.
i := 0
dot := -1
for i < len(p) && p[i] != '/' {
switch p[i] {
case 0, '\\', ':':
return "", errInvalidPath
case '.':
if dot < 0 {
dot = i
}
}
i++
}
Expand All @@ -39,22 +34,8 @@ func fromFS(path string) (string, error) {
} else {
p = ""
}
// Trim the extension and look for a reserved name.
base := part
if dot >= 0 {
base = part[:dot]
}
if isReservedName(base) {
if dot < 0 {
return "", errInvalidPath
}
// The path element is a reserved name with an extension.
// Some Windows versions consider this a reserved name,
// while others do not. Use FullPath to see if the name is
// reserved.
if p, _ := syscall.FullPath(part); len(p) >= 4 && p[:4] == `\\.\` {
return "", errInvalidPath
}
if IsReservedName(part) {
return "", errInvalidPath
}
}
if containsSlash {
Expand All @@ -70,23 +51,88 @@ func fromFS(path string) (string, error) {
return path, nil
}

// isReservedName reports if name is a Windows reserved device name.
// IsReservedName reports if name is a Windows reserved device name.
// It does not detect names with an extension, which are also reserved on some Windows versions.
//
// For details, search for PRN in
// https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file.
func isReservedName(name string) bool {
if 3 <= len(name) && len(name) <= 4 {
func IsReservedName(name string) bool {
// Device names can have arbitrary trailing characters following a dot or colon.
base := name
for i := 0; i < len(base); i++ {
switch base[i] {
case ':', '.':
base = base[:i]
}
}
// Trailing spaces in the last path element are ignored.
for len(base) > 0 && base[len(base)-1] == ' ' {
base = base[:len(base)-1]
}
if !isReservedBaseName(base) {
return false
}
if len(base) == len(name) {
return true
}
// The path element is a reserved name with an extension.
// Some Windows versions consider this a reserved name,
// while others do not. Use FullPath to see if the name is
// reserved.
if p, _ := syscall.FullPath(name); len(p) >= 4 && p[:4] == `\\.\` {
return true
}
return false
}

func isReservedBaseName(name string) bool {
if len(name) == 3 {
switch string([]byte{toUpper(name[0]), toUpper(name[1]), toUpper(name[2])}) {
case "CON", "PRN", "AUX", "NUL":
return len(name) == 3
return true
}
}
if len(name) >= 4 {
switch string([]byte{toUpper(name[0]), toUpper(name[1]), toUpper(name[2])}) {
case "COM", "LPT":
return len(name) == 4 && '1' <= name[3] && name[3] <= '9'
if len(name) == 4 && '1' <= name[3] && name[3] <= '9' {
return true
}
// Superscript ¹, ², and ³ are considered numbers as well.
switch name[3:] {
case "\u00b2", "\u00b3", "\u00b9":
return true
}
return false
}
}

// Passing CONIN$ or CONOUT$ to CreateFile opens a console handle.
// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea#consoles
//
// While CONIN$ and CONOUT$ aren't documented as being files,
// they behave the same as CON. For example, ./CONIN$ also opens the console input.
if len(name) == 6 && name[5] == '$' && equalFold(name, "CONIN$") {
return true
}
if len(name) == 7 && name[6] == '$' && equalFold(name, "CONOUT$") {
return true
}
return false
}

func equalFold(a, b string) bool {
if len(a) != len(b) {
return false
}
for i := 0; i < len(a); i++ {
if toUpper(a[i]) != toUpper(b[i]) {
return false
}
}
return true
}

func toUpper(c byte) byte {
if 'a' <= c && c <= 'z' {
return c - ('a' - 'A')
Expand Down

0 comments on commit e944bc2

Please sign in to comment.