hermes-agent/tests/plugins/memory
pprism13 9291b786b4 fix(openviking): sanitize embedded newlines when writing .env secrets
`_write_env_vars` in the OpenViking memory provider interpolates each
secret straight into a `KEY=VALUE` line, but the values only ever pass
through `_clean_config_value`, whose `value.strip()` trims surrounding
whitespace and leaves internal CR/LF intact. Because the file is strictly
line-oriented and is re-read via `read_text().splitlines()`, a value that
carries an embedded newline spills onto a second physical line, and the
tail is re-parsed as an independent `KEY=VALUE` entry on the next round
trip. A secret pasted with a trailing record (e.g. an `OPENVIKING_API_KEY`
copied with an extra line) therefore injects an arbitrary additional
variable into the persisted credentials file and silently corrupts it.

The fix neutralizes the line terminators at the single chokepoint where
values reach the file. A small `_env_line_safe` helper strips `\r`, `\n`,
and the NUL byte from each value, and both write sites in `_write_env_vars`
(the existing-key update branch and the appended-key branch) route through
it, so a value can only ever occupy the single line it is written on.

## What does this PR do?

Hardens the OpenViking memory provider's `.env` writer so a malformed or
pasted secret value can no longer break out of its `KEY=VALUE` line and
inject a rogue variable into the profile-scoped credentials file.

## Related Issue

N/A

## Type of Change

- [x] 🐛 Bug fix (non-breaking change that fixes an issue)

## Changes Made

- `plugins/memory/openviking/__init__.py`: add `_env_line_safe()` which
  removes `\r`, `\n`, and `\x00` from a value, and apply it to both the
  updated-key and appended-key write branches in `_write_env_vars()`.
- `tests/plugins/memory/test_openviking_provider.py`: add two regression
  tests covering a fresh write and an in-place key update with embedded
  CR/LF, asserting no injected line survives the read-back.

## How to Test

1. Run the targeted tests:
   `pytest tests/plugins/memory/test_openviking_provider.py -k env_writer -q`
2. Reverting the `_env_line_safe` sanitization makes
   `test_openviking_env_writer_strips_embedded_newlines_in_values` and
   `test_openviking_env_writer_strips_newlines_when_updating_existing_key`
   fail with a rogue `INJECTED_KEY=`/`ROGUE=1` line appearing in the file,
   confirming the tests pin the bug.
3. `ruff check plugins/memory/openviking/__init__.py` and
   `python scripts/check-windows-footguns.py plugins/memory/openviking/__init__.py`
   both pass.

## Checklist

### Code

- [x] I've read the Contributing Guide
- [x] My commit messages follow Conventional Commits
- [x] I searched for existing PRs to make sure this isn't a duplicate
- [x] My PR contains only changes related to this fix
- [x] I've run the relevant tests and they pass
- [x] I've added tests for my changes (required for bug fixes)
- [x] I've tested on my platform: macOS 15 (Darwin 25.5)

### Documentation & Housekeeping

- [x] I've updated relevant documentation (docstrings) — or N/A
- [x] I've updated `cli-config.yaml.example` if I added/changed config keys — N/A
- [x] I've updated `CONTRIBUTING.md` or `AGENTS.md` if I changed architecture or workflows — N/A
- [x] I've considered cross-platform impact (strips CR as well as LF) — done
- [x] I've updated tool descriptions/schemas if I changed tool behavior — N/A

(cherry picked from commit f29dd2df84)
2026-07-24 13:00:53 +05:30
..
__init__.py fix: mem0 API v2 compat, prefetch context fencing, secret redaction (#5423) 2026-04-05 22:43:33 -07:00
test_byterover_provider.py fix(byterover): honor auto extract config 2026-06-27 04:04:15 -07:00
test_config_schema.py revert(memory): drop the provider actions extension point 2026-07-10 15:41:52 -04:00
test_hindsight_config_schema.py refactor(memory): move provider config schemas into their plugins 2026-07-02 16:55:39 -04:00
test_hindsight_provider.py fix(hindsight): lazy-install cloud client dependency 2026-06-19 07:36:28 -07:00
test_holographic_auto_extract.py fix(memory): preserve genuine pre-delimiter content in merged compaction rows 2026-07-22 06:59:14 -07:00
test_holographic_retrieval.py fix(memory/holographic): sanitize FTS5 queries for natural-language recall 2026-06-30 15:55:11 -07:00
test_holographic_shutdown_closes_db.py fix(memory/holographic): close DB connection on shutdown instead of leaking to GC (#54133) 2026-06-28 02:41:52 -07:00
test_holographic_store.py fix(memory): resolve() the shared-connection registry key; symlink test 2026-07-09 18:17:40 -07:00
test_honcho_config_schema.py refactor(memory): move provider config schemas into their plugins 2026-07-02 16:55:39 -04:00
test_mem0_backend.py fix(mem0): migrate legacy OSS base URL aliases 2026-07-17 13:49:29 -07:00
test_mem0_providers.py feat(mem0): v3 API, OSS mode, update/delete tools, telemetry & review fixes (#15624) 2026-06-22 12:30:47 +00:00
test_mem0_setup.py fix(mem0): migrate legacy OSS base URL aliases 2026-07-17 13:49:29 -07:00
test_mem0_v3.py fix(mem0): prune dead get_all, wire rerank config default, warn on MEM0_HOST env override 2026-07-08 01:57:11 +05:30
test_memory_lazy_install.py fix(memory): lazy-install supermemory + mem0 SDKs like honcho/hindsight 2026-06-29 00:25:36 -07:00
test_openviking_provider.py fix(openviking): sanitize embedded newlines when writing .env secrets 2026-07-24 13:00:53 +05:30
test_retaindb_provider.py fix(memory): guard local uploads against credential reads 2026-07-05 03:14:49 -07:00
test_supermemory_provider.py fix(supermemory): complete self-hosted endpoint routing 2026-07-20 00:40:40 -07:00