Browse Source

[windows] Fix leak in `glob`.

Jeroen van Rijn 3 years ago
parent
commit
df32b5b46c

+ 1 - 0
core/os/dir_windows.odin

@@ -82,6 +82,7 @@ read_dir :: proc(fd: Handle, n: int, allocator := context.allocator) -> (fi: []F
 	wpath_search[len(wpath)+2] = 0
 
 	path := cleanpath_from_buf(wpath)
+	defer delete(path)
 
 	find_data := &win32.WIN32_FIND_DATAW{}
 	find_handle := win32.FindFirstFileW(raw_data(wpath_search), find_data)

+ 0 - 1
core/os/stat.odin

@@ -2,7 +2,6 @@ package os
 
 import "core:time"
 
-
 File_Info :: struct {
 	fullpath: string,
 	name:     string,

+ 6 - 6
core/os/stat_windows.odin

@@ -80,7 +80,7 @@ stat :: proc(name: string, allocator := context.allocator) -> (File_Info, Errno)
 	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 {
 		return {}, ERROR_INVALID_HANDLE
 	}
@@ -94,14 +94,14 @@ fstat :: proc(fd: Handle, allocator := context.allocator) -> (File_Info, Errno)
 	h := win32.HANDLE(fd)
 	switch win32.GetFileType(h) {
 	case win32.FILE_TYPE_PIPE, win32.FILE_TYPE_CHAR:
-		fi: File_Info
-		fi.fullpath = path
 		fi.name = basename(path)
 		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)
 	}
-
-	return file_info_from_get_file_information_by_handle(path, h)
+	fi.fullpath = path
+	return
 }
 
 

+ 10 - 4
core/path/filepath/match.odin

@@ -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) {
+	context.allocator = allocator
+
 	if !has_meta(pattern) {
 		// TODO(bill): os.lstat on here to check for error
-		m := make([]string, 1, allocator)
+		m := make([]string, 1)
 		m[0] = pattern
 		return m[:], .None
 	}
@@ -232,6 +234,7 @@ glob :: proc(pattern: string, allocator := context.allocator) -> (matches: []str
 	when ODIN_OS == .Windows {
 		temp_buf: [8]byte
 		volume_len, dir = clean_glob_path_windows(dir, temp_buf[:])
+
 	} else {
 		dir = clean_glob_path(dir)
 	}
@@ -246,7 +249,7 @@ glob :: proc(pattern: string, allocator := context.allocator) -> (matches: []str
 	if err != .None {
 		return
 	}
-	dmatches := make([dynamic]string, 0, 0, allocator)
+	dmatches := make([dynamic]string, 0, 0)
 	for d in m {
 		dmatches, err = _glob(d, file, &dmatches)
 		if err != .None {
@@ -258,11 +261,13 @@ glob :: proc(pattern: string, allocator := context.allocator) -> (matches: []str
 	}
 	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 {
 		m = matches^
 	} 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)
 		defer os.file_info_delete(file_info)
+
 		if ferr != 0 {
 			return
 		}

+ 1 - 1
core/path/filepath/path.odin

@@ -122,6 +122,7 @@ clean :: proc(path: string, allocator := context.allocator) -> string {
 		vol_and_path = original_path,
 		vol_len = vol_len,
 	}
+	defer lazy_buffer_destroy(out)
 
 	r, dot_dot := 0, 0
 	if rooted {
@@ -170,7 +171,6 @@ clean :: proc(path: string, allocator := context.allocator) -> string {
 	cleaned, new_allocation := from_slash(s)
 	if new_allocation {
 		delete(s)
-		lazy_buffer_destroy(out)
 	}
 	return cleaned
 }

+ 4 - 3
core/sys/windows/util.odin

@@ -45,7 +45,9 @@ utf8_to_wstring :: proc(s: string, allocator := context.temp_allocator) -> wstri
 	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 {
 		return ""
 	}
@@ -60,7 +62,7 @@ wstring_to_utf8 :: proc(s: wstring, N: int, allocator := context.temp_allocator)
 	// also null terminated.
 	// 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.
-	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)
 	if n1 == 0 {
@@ -74,7 +76,6 @@ wstring_to_utf8 :: proc(s: wstring, N: int, allocator := context.temp_allocator)
 			break
 		}
 	}
-
 	return string(text[:n])
 }
 

+ 1 - 1
tests/core/strings/test_core_strings.odin

@@ -1,4 +1,4 @@
-package test_core_image
+package test_core_strings
 
 import "core:strings"
 import "core:testing"