86 Commits

Author SHA1 Message Date
2952466abd feat(history): consolidate logging controls and add dbbackend statusbar indicator
Deprecate /logging command in favor of /history for chat logging control.
/history off now stops persistence (sets PREF_DBLOG=off + PREF_CHLOG=false)
in addition to hiding history on open. /history on restores persistence
(re-enabling PREF_DBLOG=on if it was off) and PREF_CHLOG.

statusbar
- PREF_STATUSBAR_SHOW_DBBACKEND (default ON) gates the [sqlite] /
  [flatfile] indicator; toggle via "/statusbar show|hide dbbackend"

/history off|on
- "/history off" now stops persistence as well as hiding history on
  open: sets PREF_DBLOG=off + PREF_CHLOG=false in addition to
  PREF_HISTORY=false
- "/history on" restores persistence (re-enabling PREF_DBLOG=on if
  it was off) and PREF_CHLOG, in addition to PREF_HISTORY=true

/logging
- Deprecated /logging command. It now prints a single notice
  pointing to /history; CMD_PREAMBLE trimmed (min_args=0, no
  setting_func, syntax/args/examples dropped); subcommand 'group'
  removed from autocomplete
- All "use '/logging chat on' to enable" hints replaced with
  "/history on" across /omemo-log, /pgp-log, /otr-log, and /ox-log

/privacy logging
- Single-pass validation across {on, off, redact, flatfile}
- Backend-switching values (on, flatfile) now take effect
  immediately when connected (via log_database_switch_backend),
  matching "/history switch" behaviour; off/redact only flip
  pref bits and keep the live backend open

/correction off
- win_print_outgoing and win_print_outgoing_with_receipt now gate
  _win_correct on PREF_CORRECTION_ALLOW, matching incoming-msg
  paths. Previously a peer's correction reflected via XEP-0280
  carbons (or the user's own /correct invocation) was applied
  in-buffer regardless of the pref

console
- Drop orphaned /logging chat reference from cons_privacy_setting()
- Delete cons_logging_setting() and remove its call from
  cons_show_log_prefs()

autocomplete
- Add dbbackend to statusbar_show_ac
- Remove logging_ac entries for chat/group subcommands
- Remove _logging_autocomplete() param handler for chat subcommand

database_flatfile
- Two local g_strndup allocations switched from char* with manual
  g_free to auto_gchar gchar* for automatic cleanup

tests
- Update test_cmd_otr.c to expect new /history-on warning messages

@author: jabber.developer2 <jabber.developer2@jabber.space>
2026-05-16 15:33:42 +00:00
3f36c303c2 feat(history): flat-file backend with bidirectional SQLite migration
A flat-file alternative to the SQLite chatlog backend with runtime
switching, full migration tooling, integrity verification, and a
synthetic load harness. SQLite remains the default; both backends share
one dispatch layer (db_backend_t vtable) so callers don't change.

Storage layout
- Per-contact append-only `flatlog/<account>/<contact>/history.log`
  under XDG_DATA_HOME, one line per message
- Single-line file header with embedded format-version marker
  (FLATFILE_FORMAT_VERSION); reader warns on missing or mismatched
  marker, writer and checker stay in sync via preprocessor
  stringification
- Deterministic key=value metadata (`id`, `aid`, `corrects`, `to`,
  `to_res`, `read`) plus escaped body \u2014 `\|`, `\]`, `\\`, `\n`, `\r`
  literals prevent log injection
- Sparse byte-offset index (FF_INDEX_STEP=500) per contact for
  O(log n) time-range lookups; rebuilt on inode / size / mtime
  change, extended in-place when the file just grew
- Per-contact GHashTable caches for archive_id presence and
  stanza_id \u2192 from_jid mapping (O(1) MAM dedup, O(1) LMC sender
  validation)

Hardening
- Path-traversal protection: JID directory name normalisation
  (`@` \u2192 `_at_`, slashes and `..` rejected at construction); every
  per-contact path is anchored under the account's flatlog/
  directory and validated before open
- Symlink-attack protection: every fopen / open uses O_NOFOLLOW; on
  ELOOP the operation aborts with an error rather than following
- Filesystem permissions: log files created with mode 0600,
  directories with mode 0700; both enforced at creation, verified
  on each open and reported on drift by `/history verify`
- Atomic crash-safe export: write to a temp file via mkstemp (mode
  0600, random suffix, no name collisions between concurrent
  exports), fsync, then rename \u2014 partial state never replaces the
  live file
- Concurrency: advisory flock(LOCK_EX) held for the duration of
  every write, including append from live messages and full rewrite
  from export, so two profanity processes can't interleave bytes
  on the same log
- DoS / abuse guards:
    * FF_MAX_LINE_LEN = 10 MB \u2014 lines longer than this are rejected
      at read with a warning; the parser will not allocate
      unbounded memory for a single record
    * FF_MAX_LMC_DEPTH = 100 \u2014 `corrects:` chain walk stops at this
      depth and emits a warning, preventing a malicious correction
      cycle from spinning the apply pass
    * FF_VERSION_SCAN_MAX = 16 \u2014 header version probe never reads
      past 16 leading comment lines, even on garbage input
    * Empty / inverted byte-range early-return in page-up read path
      so a malformed time filter cannot cause an unbounded scan
    * Zero-entry index guard so a file whose every line failed to
      parse cannot cause a NULL deref on later page-up
- LMC sender validation: an incoming correction whose sender does
  not match the original message's sender is rejected at write
  time and surfaced via cons_show_error; a cycle in the apply pass
  is broken via a visited-set
- jid_create_from_bare_and_resource treats NULL, empty string, and
  the literal "(null)" as no resource and returns a bare jid;
  similar normalisation for barejid eliminates the legacy
  "user@host/(null)" artefact that leaked into stored fulljids
  whenever g_strdup_printf("%s", NULL) ran inside create_fulljid

Commands
- `/history switch sqlite|flatfile` \u2014 runtime backend swap, closes
  the old backend and opens the new one without reconnecting
- `/history export [<jid>]` \u2014 SQLite -> flat-file, merging with any
  existing flatlog (dedup keyed on a SHA-256 hash mixing stanza_id,
  timestamp, from_jid, body \u2014 robust against id reuse by older
  clients)
- `/history import [<jid>]` \u2014 flat-file -> SQLite, same merge
  semantics, runs inside a single SQLite transaction with rollback
  on per-contact failure
- `/history verify [<jid>]` \u2014 integrity check; emits a structured
  list of issues (ERROR / WARNING / INFO) per file:
    * file-level: missing log, wrong permissions (\u2260 0600), UTF-8
      BOM present, CRLF line endings, empty file
    * line-level: invalid UTF-8 (with byte offset), embedded
      control characters, unparsable lines, timestamps out of
      order, duplicate `id:` and `aid:` (tracked separately so a
      stanza/archive id collision isn't double-reported)
    * cross-line: broken `corrects:` references whose target id is
      not present in the file
- `/history backend` \u2014 show currently active backend
- Active backend indicator `[sqlite]` / `[flatfile]` in the status
  bar next to the JID
- Roster-JID autocomplete for verify / export / import
- export and import open a SQLite handle on demand when the
  flatfile backend is currently active, so migration works
  regardless of which backend is live

Tests
- Unit: database_export (parser round-trip, escape/unescape, dedup
  key stability, JID normalisation), database_stress (14 cases
  exercising rapid writes, large messages, deep LMC chains, MAM
  dedup, concurrent contacts)
- Functional: history persistence across reconnects, export /
  import round-trip with content equality, MUC migration,
  timestamp normalisation across timezones
- Bench harness P1\u2013P5 (synthetic load: bulk insert, time-range
  read, page-up scroll, MAM ingest, mixed workload) and failure
  modes F1\u2013F17 (page-up cursor and forward-iteration symmetry,
  oversized lines, MAM dedup, LMC depth and cycles, BOM/CRLF,
  missing log, empty file, mtime+inode flip, broken corrects, etc.)
- All bench tests integrate with the existing make targets and
  emit CSV rows for baseline comparison

Author: jabber.developer2 <jabber.developer2@jabber.space>
Reviewed-by: jabber.developer <jabber.developer@jabber.space>
2026-05-05 19:26:07 +00:00
f8826b7c79 ci: improve CI stability with parallel builds and Valgrind
Major changes:
Run 4 build configurations in parallel with Valgrind on Linux
Add test failure detection verification (meta-test)
Port allocation per build to prevent conflicts in parallel runs
Add --coverage-only flag for dedicated coverage builds
Code quality:

Add TEST_GROUPS constant, CMOCKA patterns, helper functions
Organize ci-build.sh into sections
2026-02-02 17:47:05 +01:00
85c817ee8c ci: speed up builds 4x with parallel tests, coverage, and ccache
Split functional tests into 4 parallel groups and add check-functional-parallel target (~3x faster CI runs).
Add branch-aware LCOV coverage reporting with new --enable-coverage option and lcov summary in CI pipeline.
Enable ccache via -C configure flag for faster recompilations.
Install lcov in all Docker images and use --depth 1 git clones + parallel make -j$(nproc) for quicker container builds.
Update CONTRIBUTING.md with instructions for parallel test groups and adding new ones.

All changes are tightly related CI/performance improvements developed in sequence. No external service uploads (e.g. Codecov skipped due to Gitea incompatibility).
2026-01-21 16:35:17 +01:00
6a394ae2e5 fix: Increase scrollback buffer height for chat rendering (PAD_SIZE)
f27fa98 commit introduced issue of scrolling seemingly randomly being stuck and the following message flood in the logs: "WRN: Ncurses Overflow..."

A pad is an off-screen buffer — larger than the visible terminal screen — that you can scroll, render parts of, or update selectively.

Unlike regular windows, a pad is not tied to screen size. You can create a pad that's 1,000 lines tall, even if your terminal is only 40 lines tall.

This commit addresses the issue by increasing PAD_SIZE to a reasonable number,
allowing messages from buffer to be displayed without overflowing NCurses' window size (maxy).

Minor change: add .cache folder to gitignore
2025-07-01 16:42:03 +02:00
Michael Vetter
bf24d79990 Add plist to gitignore 2025-03-13 09:48:32 +01:00
Steffen Jaeckel
f67c76c032 Add make target my-prof.supp
This creates a "as personal as possible" Valgrind suppressions file.

Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
2025-01-28 16:43:13 +01:00
Steffen Jaeckel
970cb706fb Minor changes
* slightly improve PR template
* update gitignore

Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de>
2023-10-04 17:02:10 +02:00
John Hernandez
bed5c02c0d Add vscode support to .gitignore 2023-04-18 14:28:30 +02:00
Steffen Jaeckel
e9aaba938b minor changes
* fix typo
* less code duplication
* less `GString` usage
* more `auto_gchar` usage
* document connecting to servers supporting SASL ANONYMOUS
* ignore valgrind output

Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de>
2023-01-18 20:02:46 +01:00
Steffen Jaeckel
53a7689a58 update gitignore
Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de>
2022-03-30 18:26:10 +02:00
William Wennerström
62cbad1c6e Add I/O error handling and use filenames instead of file descriptors 2020-11-16 21:58:09 +01:00
Michael Vetter
7f956aa4f5 Add zipfiles to gitignore 2020-02-03 16:25:50 +01:00
Michael Vetter
d169312a84 Update gitignore 2020-01-30 11:55:05 +01:00
James Booth
7bc160c24e Update plugin API docs 2016-08-02 23:17:28 +01:00
James Booth
7314a13248 Update gitignore, added python API docs Makefile 2016-08-02 22:54:34 +01:00
James Booth
a308f5e4f1 Add python plugin hook docs 2016-07-29 00:27:26 +01:00
James Booth
1bc6941847 Update gitignore 2016-07-29 00:16:09 +01:00
James Booth
47dfa6c3fc Merge branch 'master' into python3
Conflicts:
	.gitignore
2016-07-24 01:22:29 +01:00
James Booth
458334a2c7 Update gitignore 2016-07-24 01:10:54 +01:00
James Booth
b68d2ce106 Update gitignore 2016-07-19 23:44:38 +01:00
James Booth
697db019d5 Merge remote-tracking branch 'Dav1d23/master'
Conflicts:
	Makefile.am
	install-all.sh
2016-04-11 00:23:36 +01:00
James Booth
9d782fa665 Added doxygen settings for C plugin API 2016-03-17 22:16:42 +00:00
James Booth
41fe8c22b1 Added C plugin code from plugins branch 2016-02-14 22:28:55 +00:00
James Booth
d944e8252e Updated .gitignore 2015-08-09 00:21:20 +01:00
James Booth
362c1d81ae Added codelite commands file to .gitignore 2015-06-13 00:34:36 +01:00
James Booth
68ed20f10d Moved all tests to tests folder 2015-06-12 23:53:30 +01:00
James Booth
c182f3ecd6 Added temp config files to gitignore 2015-06-12 23:05:30 +01:00
James Booth
b1375328df Tidied .gitignore 2015-06-12 22:46:52 +01:00
James Booth
e919445231 Renamed stabbertests -> functionaltests 2015-05-28 18:56:16 +01:00
James Booth
6d6bb64588 Moved tests -> unittests 2015-05-28 18:50:55 +01:00
James Booth
e295a474dc Added more connect tests 2015-05-24 20:31:18 +01:00
James Booth
97c5072f56 Added stabber testsuite 2015-05-17 01:11:03 +01:00
James Booth
5e1ad0b0d2 Added profanity.sh (OSX helper script for codelite) to .gitignore 2015-03-04 22:37:42 +00:00
James Booth
268c33e1c6 Free resource lists on /account command 2015-02-09 19:50:41 +00:00
James Booth
e0dfe4832b Added code to generate HTML command reference for website 2015-02-08 00:42:21 +00:00
James Booth
1e35b76bf9 Added callgrind.out files to gitignore 2015-02-06 21:41:24 +00:00
James Booth
e94b604b0c Updated gitignore 2015-01-14 13:26:54 +00:00
James Booth
f7843def2f Added chat session tests 2015-01-06 21:22:09 +00:00
James Booth
1814dcdd26 Added m4 directory to gitignore 2014-10-30 23:24:45 +00:00
James Booth
bca5a5f78d Merge branch 'master' into muc_roles
Conflicts:
	.gitignore
2014-09-30 20:46:26 +01:00
James Booth
fbeb107cbe Dont check for var attribute on form fields of type fixed 2014-09-30 20:44:00 +01:00
James Booth
2dacfc823a Updated gitignore 2014-09-29 00:00:11 +01:00
James Booth
ef34ddc1eb Updated gitignore 2014-09-28 23:32:06 +01:00
James Booth
51bb5f9e60 Added codelite project to gitignore 2014-09-28 23:04:16 +01:00
James Booth
62dd30ff90 Added push all script to .gitignore 2014-05-12 23:33:14 +01:00
James Booth
f44cf86f23 Added cppcheck.out to .gitignore 2014-04-26 00:42:54 +01:00
James Booth
ff18572ef0 Updated .gitignore 2014-04-06 23:51:34 +01:00
Dmitry Podgorny
0fbaa6f5ee fixed build error when make run with -jN option
Race can occur when gitversion file isn't fully generated before
it is used.
2014-03-06 02:06:22 +02:00
James Booth
185d72e2ce Added DS store to gitignore 2014-02-12 20:54:01 +00:00