address uaf in portfolio command watchlist
This commit is contained in:
parent
473a94976d
commit
9aaa374f12
1 changed files with 24 additions and 13 deletions
|
|
@ -181,8 +181,23 @@ pub fn run(ctx: *framework.RunCtx, parsed: ParsedArgs) !void {
|
||||||
}
|
}
|
||||||
}.f);
|
}.f);
|
||||||
|
|
||||||
|
// Separate watchlist file (backward compat). Loaded here at the run
|
||||||
|
// scope - NOT inside the collection block below - so its symbol
|
||||||
|
// strings outlive the `display` call at the end of `run`.
|
||||||
|
// `watch_list` (and `watch_prices`' keys) borrow these slices;
|
||||||
|
// freeing them before display - the previous behavior, where the
|
||||||
|
// load + `defer freeWatchlist` lived inside the collection block -
|
||||||
|
// rendered the file's watch symbols as freed-memory garbage on the
|
||||||
|
// CLI. The TUI is unaffected: it keeps watchlist symbols in its
|
||||||
|
// long-lived arena.
|
||||||
|
const wl_syms: ?[][]const u8 = if (watchlist_path) |wl_path|
|
||||||
|
cli.loadWatchlist(io, allocator, wl_path)
|
||||||
|
else
|
||||||
|
null;
|
||||||
|
defer cli.freeWatchlist(allocator, wl_syms);
|
||||||
|
|
||||||
// Collect watch symbols and their prices for display.
|
// Collect watch symbols and their prices for display.
|
||||||
// Includes watch lots from portfolio + symbols from separate watchlist file.
|
// Includes watch lots from portfolio + symbols from the watchlist file.
|
||||||
var watch_list: std.ArrayList([]const u8) = .empty;
|
var watch_list: std.ArrayList([]const u8) = .empty;
|
||||||
defer watch_list.deinit(allocator);
|
defer watch_list.deinit(allocator);
|
||||||
var watch_prices = std.StringHashMap(f64).init(allocator);
|
var watch_prices = std.StringHashMap(f64).init(allocator);
|
||||||
|
|
@ -208,18 +223,14 @@ pub fn run(ctx: *framework.RunCtx, parsed: ParsedArgs) !void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Separate watchlist file (backward compat)
|
// Symbols from the separate watchlist file (loaded above).
|
||||||
if (watchlist_path) |wl_path| {
|
if (wl_syms) |syms_list| {
|
||||||
const wl_syms = cli.loadWatchlist(io, allocator, wl_path);
|
for (syms_list) |sym| {
|
||||||
defer cli.freeWatchlist(allocator, wl_syms);
|
if (watch_seen.contains(sym)) continue;
|
||||||
if (wl_syms) |syms_list| {
|
try watch_seen.put(sym, {});
|
||||||
for (syms_list) |sym| {
|
try watch_list.append(allocator, sym);
|
||||||
if (watch_seen.contains(sym)) continue;
|
if (svc.getCachedLastClose(sym)) |close| {
|
||||||
try watch_seen.put(sym, {});
|
try watch_prices.put(sym, close);
|
||||||
try watch_list.append(allocator, sym);
|
|
||||||
if (svc.getCachedLastClose(sym)) |close| {
|
|
||||||
try watch_prices.put(sym, close);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue