mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 23:28:48 +00:00
[windows] Fix leak in glob.
This commit is contained in:
@@ -82,6 +82,7 @@ read_dir :: proc(fd: Handle, n: int, allocator := context.allocator) -> (fi: []F
|
|||||||
wpath_search[len(wpath)+2] = 0
|
wpath_search[len(wpath)+2] = 0
|
||||||
|
|
||||||
path := cleanpath_from_buf(wpath)
|
path := cleanpath_from_buf(wpath)
|
||||||
|
defer delete(path)
|
||||||
|
|
||||||
find_data := &win32.WIN32_FIND_DATAW{}
|
find_data := &win32.WIN32_FIND_DATAW{}
|
||||||
find_handle := win32.FindFirstFileW(raw_data(wpath_search), find_data)
|
find_handle := win32.FindFirstFileW(raw_data(wpath_search), find_data)
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package os
|
|||||||
|
|
||||||
import "core:time"
|
import "core:time"
|
||||||
|
|
||||||
|
|
||||||
File_Info :: struct {
|
File_Info :: struct {
|
||||||
fullpath: string,
|
fullpath: string,
|
||||||
name: string,
|
name: string,
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ stat :: proc(name: string, allocator := context.allocator) -> (File_Info, Errno)
|
|||||||
return _stat(name, attrs, allocator)
|
return _stat(name, attrs, allocator)
|
||||||
}
|
}
|
||||||
|
|
||||||
fstat :: proc(fd: Handle, allocator := context.allocator) -> (File_Info, Errno) {
|
fstat :: proc(fd: Handle, allocator := context.allocator) -> (fi: File_Info, errno: Errno) {
|
||||||
if fd == 0 {
|
if fd == 0 {
|
||||||
return {}, ERROR_INVALID_HANDLE
|
return {}, ERROR_INVALID_HANDLE
|
||||||
}
|
}
|
||||||
@@ -94,14 +94,14 @@ fstat :: proc(fd: Handle, allocator := context.allocator) -> (File_Info, Errno)
|
|||||||
h := win32.HANDLE(fd)
|
h := win32.HANDLE(fd)
|
||||||
switch win32.GetFileType(h) {
|
switch win32.GetFileType(h) {
|
||||||
case win32.FILE_TYPE_PIPE, win32.FILE_TYPE_CHAR:
|
case win32.FILE_TYPE_PIPE, win32.FILE_TYPE_CHAR:
|
||||||
fi: File_Info
|
|
||||||
fi.fullpath = path
|
|
||||||
fi.name = basename(path)
|
fi.name = basename(path)
|
||||||
fi.mode |= file_type_mode(h)
|
fi.mode |= file_type_mode(h)
|
||||||
return fi, ERROR_NONE
|
errno = ERROR_NONE
|
||||||
|
case:
|
||||||
|
fi, errno = file_info_from_get_file_information_by_handle(path, h)
|
||||||
}
|
}
|
||||||
|
fi.fullpath = path
|
||||||
return file_info_from_get_file_information_by_handle(path, h)
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -220,9 +220,11 @@ get_escape :: proc(chunk: string) -> (r: rune, next_chunk: string, err: Match_Er
|
|||||||
//
|
//
|
||||||
|
|
||||||
glob :: proc(pattern: string, allocator := context.allocator) -> (matches: []string, err: Match_Error) {
|
glob :: proc(pattern: string, allocator := context.allocator) -> (matches: []string, err: Match_Error) {
|
||||||
|
context.allocator = allocator
|
||||||
|
|
||||||
if !has_meta(pattern) {
|
if !has_meta(pattern) {
|
||||||
// TODO(bill): os.lstat on here to check for error
|
// TODO(bill): os.lstat on here to check for error
|
||||||
m := make([]string, 1, allocator)
|
m := make([]string, 1)
|
||||||
m[0] = pattern
|
m[0] = pattern
|
||||||
return m[:], .None
|
return m[:], .None
|
||||||
}
|
}
|
||||||
@@ -232,6 +234,7 @@ glob :: proc(pattern: string, allocator := context.allocator) -> (matches: []str
|
|||||||
when ODIN_OS == .Windows {
|
when ODIN_OS == .Windows {
|
||||||
temp_buf: [8]byte
|
temp_buf: [8]byte
|
||||||
volume_len, dir = clean_glob_path_windows(dir, temp_buf[:])
|
volume_len, dir = clean_glob_path_windows(dir, temp_buf[:])
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
dir = clean_glob_path(dir)
|
dir = clean_glob_path(dir)
|
||||||
}
|
}
|
||||||
@@ -246,7 +249,7 @@ glob :: proc(pattern: string, allocator := context.allocator) -> (matches: []str
|
|||||||
if err != .None {
|
if err != .None {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
dmatches := make([dynamic]string, 0, 0, allocator)
|
dmatches := make([dynamic]string, 0, 0)
|
||||||
for d in m {
|
for d in m {
|
||||||
dmatches, err = _glob(d, file, &dmatches)
|
dmatches, err = _glob(d, file, &dmatches)
|
||||||
if err != .None {
|
if err != .None {
|
||||||
@@ -258,11 +261,13 @@ glob :: proc(pattern: string, allocator := context.allocator) -> (matches: []str
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
_glob :: proc(dir, pattern: string, matches: ^[dynamic]string) -> (m: [dynamic]string, e: Match_Error) {
|
_glob :: proc(dir, pattern: string, matches: ^[dynamic]string, allocator := context.allocator) -> (m: [dynamic]string, e: Match_Error) {
|
||||||
|
context.allocator = allocator
|
||||||
|
|
||||||
if matches != nil {
|
if matches != nil {
|
||||||
m = matches^
|
m = matches^
|
||||||
} else {
|
} else {
|
||||||
m = make([dynamic]string, 0, 0, context.allocator)
|
m = make([dynamic]string, 0, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -275,6 +280,7 @@ _glob :: proc(dir, pattern: string, matches: ^[dynamic]string) -> (m: [dynamic]s
|
|||||||
{
|
{
|
||||||
file_info, ferr := os.fstat(d)
|
file_info, ferr := os.fstat(d)
|
||||||
defer os.file_info_delete(file_info)
|
defer os.file_info_delete(file_info)
|
||||||
|
|
||||||
if ferr != 0 {
|
if ferr != 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -122,6 +122,7 @@ clean :: proc(path: string, allocator := context.allocator) -> string {
|
|||||||
vol_and_path = original_path,
|
vol_and_path = original_path,
|
||||||
vol_len = vol_len,
|
vol_len = vol_len,
|
||||||
}
|
}
|
||||||
|
defer lazy_buffer_destroy(out)
|
||||||
|
|
||||||
r, dot_dot := 0, 0
|
r, dot_dot := 0, 0
|
||||||
if rooted {
|
if rooted {
|
||||||
@@ -170,7 +171,6 @@ clean :: proc(path: string, allocator := context.allocator) -> string {
|
|||||||
cleaned, new_allocation := from_slash(s)
|
cleaned, new_allocation := from_slash(s)
|
||||||
if new_allocation {
|
if new_allocation {
|
||||||
delete(s)
|
delete(s)
|
||||||
lazy_buffer_destroy(out)
|
|
||||||
}
|
}
|
||||||
return cleaned
|
return cleaned
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,9 @@ utf8_to_wstring :: proc(s: string, allocator := context.temp_allocator) -> wstri
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
wstring_to_utf8 :: proc(s: wstring, N: int, allocator := context.temp_allocator) -> string {
|
wstring_to_utf8 :: proc(s: wstring, N: int, allocator := context.temp_allocator) -> (res: string) {
|
||||||
|
context.allocator = allocator
|
||||||
|
|
||||||
if N <= 0 {
|
if N <= 0 {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
@@ -60,7 +62,7 @@ wstring_to_utf8 :: proc(s: wstring, N: int, allocator := context.temp_allocator)
|
|||||||
// also null terminated.
|
// also null terminated.
|
||||||
// If N != -1 it assumes the wide string is not null terminated and the resulting string
|
// If N != -1 it assumes the wide string is not null terminated and the resulting string
|
||||||
// will not be null terminated, we therefore have to force it to be null terminated manually.
|
// will not be null terminated, we therefore have to force it to be null terminated manually.
|
||||||
text := make([]byte, n+1 if N != -1 else n, allocator)
|
text := make([]byte, n+1 if N != -1 else n)
|
||||||
|
|
||||||
n1 := WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, s, i32(N), raw_data(text), n, nil, nil)
|
n1 := WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, s, i32(N), raw_data(text), n, nil, nil)
|
||||||
if n1 == 0 {
|
if n1 == 0 {
|
||||||
@@ -74,7 +76,6 @@ wstring_to_utf8 :: proc(s: wstring, N: int, allocator := context.temp_allocator)
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return string(text[:n])
|
return string(text[:n])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package test_core_image
|
package test_core_strings
|
||||||
|
|
||||||
import "core:strings"
|
import "core:strings"
|
||||||
import "core:testing"
|
import "core:testing"
|
||||||
|
|||||||
Reference in New Issue
Block a user