| Commit message (Collapse) | Author | Age | Files | Lines |
| ... | |
| |
|
|
|
|
|
|
|
|
|
|
| |
7 ERT tests covering the card-prompt return-value contract:
- org-drill-presentation-prompt-in-mini-buffer with input-pending-p
and read-key-sequence both mocked: quit → nil, edit → 'edit,
skip → 'skip, any-other-key → t
- explicit PROMPT arg appears in the formatted full-prompt
- org-drill-presentation-prompt dispatcher routes by
org-drill-presentation-prompt-with-typing (nil → mini-buffer
variant, non-nil → in-buffer variant)
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
8 ERT tests covering hide1-firstmore, show1-lastmore, show1-firstless.
Each wraps a cond that selects between common and uncommon multicloze
presenters based on org-drill-cloze-text-weight and the entry's
total-repeats counter.
Underlying presenter functions are mocked to no-op stubs that record
which one was selected — the branch logic is what's under test, not
the (interactive) cloze-prompt itself.
Cases covered per function:
- nil weight → fall back to non-weighted variant
- invalid weight (non-positive int) → error
- non-trigger rep → common path (hide-first / show-last / skip-first)
- trigger rep → uncommon path (hide-n with appropriate force flags)
|
| |
|
|
|
|
|
|
|
|
|
|
| |
10 ERT tests covering the rating function (read-key-sequence mocked):
- Quality 0/3/5 each returns the integer rating
- Quit key returns nil, edit key returns 'edit
- Successful rating pushes quality onto session->qualities
- Non-cram rating sets a SCHEDULED stamp via smart-reschedule
- Cram mode skips the reschedule (no SCHEDULED set)
- Failure with >= leech-failure-threshold tags entry :leech:
- Failure under threshold doesn't tag :leech:
|
| |
|
|
|
|
|
| |
Every drilled card was logging "[debug] org-drill: at marker position N"
to *Messages* and flashing it in the minibuffer. Pure noise — the
print statement was clearly a leftover from diagnostic work that
never got cleaned up. Delete it.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
15 ERT tests covering:
- org-drill-goto-entry: marker → buffer + position
- org-drill-goto-drill-entry-heading: stays put on the drill heading,
walks up from a child sub-heading, errors outside any drill entry
- org-drill-command-keybinding-to-string: nil for unbound, string
for bound commands
- org-drill-push-end: appends to non-empty and empty lists
- org-drill-leitner-rebox (interactive — read-key-sequence mocked):
rating 0 resets to box 1, rating 1 decrements (with floor at 1),
rating 2 stays, ratings 3-5 promote, quit-key returns 'quit
|
| |
|
|
|
|
|
|
|
|
|
| |
10 ERT tests covering:
- org-drill--make-minibuffer-prompt: status char (N/Y/o/!/F),
cram-mode shows C, done-entries count, prompt-text passthrough
- org-drill-relearn-item: resets DRILL_LAST_INTERVAL to 0,
unschedules the entry (days-ahead = 0 path through smart-reschedule)
- org-drill-progress-message: emits on multiples of 50, silent
otherwise, includes the COLLECTED count
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
6 ERT tests covering all four days-ahead branches:
- 0 → unschedule (treat as new again)
- negative → schedule today (current-time)
- positive → schedule N days ahead
- nil → use the algorithm-computed next-interval (locks in the
numberp guard fix)
Plus property side-effects: writes DRILL_LAST_INTERVAL / EASE /
TOTAL_REPEATS via store-item-data, and TOTAL_REPEATS increments on
each call.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The function takes `days-ahead' as &optional, but the schedule cond
called `(= 0 days-ahead)' and `(cl-minusp days-ahead)' before any
type-guard, so passing nil crashed with a wrong-type-argument error.
Today's two callers (the rating-confirmation flow and the
org-drill-relearn-item helper) always pass a number, so this was
latent — but a third caller relying on the documented &optional
shape would hit it immediately.
Switched the cond to require numberp before the value comparisons,
and the default branch now falls back to the algorithm-computed
next-interval when days-ahead is nil. That matches the intent
implied by the optional signature and the docstring.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
12 ERT tests covering:
- org-drill-pop-next-pending-entry: empty session → nil, failed
prioritized over new/old, again-entries fallback, max-item limit
gates primary queues but again-entries bypasses
- org-drill-card-tag-caller: dispatches per-tag hook fn from alist,
unknown tag is silent no-op (falls through to ignore)
- org-drill-id-get-create-with-warning: creates ID and flips
warned-about-id-creation flag, doesn't re-warn (uses tempfile-
backed buffer because org-id-get requires file-visiting)
- org-drill-add-cloze-fontification: sets buffer-local cloze-regexp
and cloze-keywords from current delimiters
- org-drill-strip-all-data: yes-or-no-p gate (no-confirm = no-op,
confirm = wipes scheduling props)
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
14 ERT tests covering:
- org-drill-explain-entry-p: with/without :explain: tag, no-inherit
flag rejects parent's tag
- org-drill-end-of-entry-pos: single-heading and multi-heading subtree
bounds
- org-drill-get-verb-conjugation-info: full property read, tense-only
(mood optional), missing-required errors, tense-color highlight face
- org-drill-get-noun-info: full property read, missing-required errors,
feminine-gender orchid color from alist, unknown-gender red fallback
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
17 ERT tests covering:
- org-drill-swap: distinct indices, same-index no-op, end-to-start
- org-drill-shuffle: preserves element multiset, empty list, singleton
- org-drill-pop-random: removes-one, nil-on-empty, empties singleton
- org-drill-hide-comments: per-line overlay, no-op on comment-free buffer
- org-drill-hide-drawers: PROPERTIES drawer, multiple drawers, no-op
on drawer-free entry
- org-drill-leitner-promote: box-N → box-(N+1), graduation at box 5
(with and without org-drill-leitner-promote-to-drill-p flag)
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Plus a docs fix to org-drill-order-overdue-entries' header comment.
16 ERT tests covering:
- org-drill-entry-status: non-drill nil, empty entry nil, virgin :new,
future :future, low-quality :failed, due+short-interval :young,
due+long-interval :old, very-overdue :overdue, skipped-leech
:unscheduled, three-element return shape
- org-drill-entry-days-since-creation: with DATE_ADDED, missing without
flag (nil), missing with use-last-interval-p flag (overdue+interval)
- org-drill-order-overdue-entries: empty stays empty, non-lapsed
sorted by DUE desc, lapsed split (by DUE crossing threshold, not AGE)
appearing after sorted by AGE desc
Fixed misleading header comment at line 2888 — it claimed the lapse
split was by AGE, but the code uses DUE (cl-second). This matches
the semantic gate in org-drill--entry-lapsed-p, so the code was
right and the comment was stale. Updated the comment to state the
actual three-step sort.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
23 ERT tests covering the queue control flow:
- org-drill-entries-pending-p: empty session, current-item slot,
again-entries bypassing limits, item-count limit interaction
- org-drill-pending-entry-count: empty, sums all queues, current-item
marker check
- org-drill-maximum-duration-reached-p: nil-duration disables, cram
bypasses, fresh session under limit, old session over limit
- org-drill-maximum-item-count-reached-p: nil disables, cram bypasses,
under/at limit, includes-failed-items-p flag
- org-drill--entry-lapsed-p: feature flag gate, threshold respected
- org-drill-free-markers: explicit list, t-frees-everything
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
19 ERT tests covering the buffer-overlay machinery behind card
presentation:
- org-drill-hide-region / unhide-text: bounds, optional display
text, no-op on clean buffers, leaves unrelated overlays alone
- org-drill-hide-clozed-text / unhide-clozed-text: hides every
cloze span with org-drill-cloze-overlay-defaults category, clean
round-trip
- org-drill-hide-cloze-hints: hides only the ||hint portion when
present, no-op when absent (locks in the production fix)
- org-drill-replace-entry-text / unreplace-entry-text: covers entry
body with placeholder string overlay
- org-drill-get-entry-text: returns body text, strips text-properties
by default
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
org-drill-hide-cloze-hints checked (null (match-beginning 2)) to detect
"no hint present," but the cloze regex's hint group is an empty-allowed
alternation — the group always participates in the match, so
match-beginning is always a position, never nil.
For a card like "[Paris]" (no hint), the function fell through to
org-drill-hide-region with start = end and made a zero-width overlay.
Cosmetically harmless but accumulates one stray overlay per hint-less
cloze. On a buffer with many such cards the tracking cost is real.
Switched the guard to (= (match-beginning 2) (match-end 2)) — empty match.
Found while writing tests; locked in by tests/test-org-drill-hide-show.el's
test-org-drill-hide-cloze-hints-no-hint-no-overlay.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
27 ERT tests covering the predicates that decide whether a card appears
in today's drill session:
- org-drill-days-since-last-review / hours-since-last-review with
current-time mocked for determinism
- org-drill-entry-days-overdue: normal mode (scheduled future/past/now,
leech skip), cram mode (recent vs stale review windows)
- org-drill-entry-due-p: scheduled in past/future, non-drill, virgin
- org-drill-entry-overdue-p: factor-based threshold across last-interval
and days-overdue
- org-drill-current-scope: file → nil, file-no-restriction → file, symbol
passthrough
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
15 ERT tests covering:
- org-drill--compute-cloze-regexp: match default and custom delimiters,
hint separator, three-capture-group structure for fontification
- org-drill--compute-cloze-keywords: font-lock spec shape
- org-drill-hypothetical-next-review-date: virgin-card scheduling,
quality-monotonic next-interval, DRILL_CARD_WEIGHT damping
- org-drill-hypothetical-next-review-dates: 6-element non-decreasing list
driving the rating-prompt preview
- org-drill-strip-entry-data: scheduling-property cleanup, no-op on
virgin entry
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
11 ERT tests covering org-drill-get-item-data and store-item-data.
The user-facing contract: rate a card → state persists across sessions.
Three branches tested: virgin item (zero-list sentinel), modern DRILL_*
properties (read all six fields, partial-set falls back to defaults),
and legacy LEARN_DATA backward compat (precedence over modern, graceful
fallthrough on malformed data).
Round-trip tests document a deliberate type quirk: rounded fields (interval,
meanq, ease) come back as floats because org-drill-round-float returns
float; counters (repeats, failures, total-repeats) stay int. Numerically
lossless and scheduler-safe.
|
| |
|
|
|
|
|
|
|
|
|
| |
30 ERT tests covering org-drill-entry-last-quality, entry-failure-count,
entry-average-quality, entry-last-interval, entry-repeats-since-fail,
entry-total-repeats, entry-ease, entry-leech-p, and entry-new-p.
Documents each function's missing-property fallback behavior — three
distinct shapes: nil-by-default (last-quality, average-quality, ease),
hardcoded-zero-by-default (failure-count, last-interval, repeats-since-
fail, total-repeats), or computed from other state (new-p, leech-p).
|
| |
|
|
|
|
|
|
|
|
|
|
| |
35 ERT tests covering org-drill-round-float, org-drill-modify-e-factor,
org-drill-modify-of, org-drill-set-optimal-factor,
org-drill-initial-optimal-factor-sm5, org-drill-get-optimal-factor-sm5,
org-drill-inter-repetition-interval-sm5, org-drill-early-interval-factor,
org-drill-random-dispersal-factor, and org-drill--safe-read-learn-data.
These helpers were exercised transitively by the existing top-level
scheduler tests but had no direct unit coverage. Direct tests give
faster feedback when a helper breaks and pin each helper's contract.
|
| |
|
|
|
|
| |
The fork's primary remotes are git.cjennings.net (origin) and github.com/cjennings/org-drill (mirror). GitLab is upstream's tracker, not ours, and I'm not running the old `.gitlab-ci.yml` anywhere.
Replacement is a GitHub Actions workflow, which I captured as a follow-up with sketches for matrix versions, caching, and stages. That's a meaningful design decision rather than a file move, so I'm leaving it for its own session.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
kqr (2019-07-22) reported that drill entries whose answer lives inside a child sub-heading were silently skipped. Their example: a question in the heading text and the answer under `** The Answer`. The function returned t (empty) for such entries, so they never got presented during drill sessions.
The cause is `(outline-next-heading)` in `org-drill-entry-empty-p`. That primitive lands on the first heading at any level, including children. So the search range was metadata-end up to the child's heading line, which excluded the child's body. Bodies that lived in child sub-headings never got searched.
I switched the bound to `(org-end-of-subtree t t)`, which covers the whole subtree of the current heading and degrades gracefully at the last heading in the buffer. The reporter suggested `outline-forward-same-level`, but that primitive errors at the last sibling, which would be its own regression. `org-end-of-subtree` is the canonical Emacs idiom for this kind of bound and handles end-of-buffer correctly.
I added `tests/test-org-drill-entry-empty-p.el` with 6 ERT tests across Normal, Boundary (kqr's exact fixture), and edge categories. The two regression tests fail at HEAD before the fix and pass after.
One semantic note worth flagging: any subtree content now counts as non-empty, including bare child headings with no body of their own. The bug report is silent on that case and I expect it to be rare in practice. If anyone reports the new behavior as a regression, the fix would be to filter heading lines out of the graphical-character search.
|
| |
|
|
|
|
|
|
|
|
| |
Two reports from breadncup (issue #52 in 2023, issue #58 in 2024) said that running an org-drill session silently nulled out their `default-input-method`. The reproduction is exact: every rating prompt clears the user's persistent setting.
The cause is `(set-input-method nil)` in `org-drill--read-key-sequence`. When `current-input-method` is nil, calling `set-input-method` with nil clears `default-input-method` as a documented side effect. The unwind-protect on the way back has the symmetric problem, since it passes the captured nil. The fix is to use the primitives that are scoped to current state. `deactivate-input-method` and `activate-input-method` don't touch `default-input-method`, and I wrap each call in a guard so the function is a no-op when no input method is active.
The same pattern lives in `org-drill-response-get-buffer-create`, which propagates the caller's input method into the response buffer. When the caller has no input method active, the captured value is nil and `(set-input-method nil)` runs in the new buffer, clearing `default-input-method` again. I applied the same guard there.
I added `tests/test-org-drill-read-key-sequence.el` with 6 ERT tests across Normal, Boundary (the bug case), and Error categories. The four regression tests fail at HEAD before the fix and pass after.
|
| |
|
|
|
|
|
|
|
|
| |
I want a stronger maintainer-discipline baseline as I take over more of this project, so I added four targets that are common in Emacs-Lisp packages.
`make lint` runs `checkdoc`, `package-lint`, and `elisp-lint` over `org-drill.el`. It's informational for now and doesn't fail on findings, because the existing source has known docstring and style debt to clear. I'll re-tighten to a hard gate after the docstring pass is done. `make compile` byte-compiles the source with `byte-compile-error-on-warn nil`, matching the existing `build` target's leniency. `make validate-parens` is a fast structural check that surfaces the line of the offending paren without needing a full byte-compile pass.
I also added a `:slow` tag filter to the default ERT runners. `test-unit`, `test-integration`, `test-file`, and `coverage` now run with `'(not (tag :slow))`. Tests tagged `:slow` get skipped on the fast feedback path. `test-name` is left alone, since a pattern argument means the user wants those tests run whether or not they're tagged slow.
Cask gets `package-lint` and `elisp-lint` as development deps. `.gitignore` gets `*-autoloads.el` so the Cask build artifact stays out.
|
| |
|
|
|
|
|
|
| |
I added a regression test for `org-drill-time-to-inactive-org-timestamp` to lock in the cherry-pick from commit 4c6e62a, which fixed upstream issue #59 on the GitLab tracker.
Chipschap reported timestamps like `[Y-08-27 Wed 16:%]` getting written into DRILL_LAST_REVIEWED. The root cause is that Org 9.6+ dropped the angle brackets around `(cdr org-time-stamp-formats)`, so the original `(substring ... 1 -1)` started slicing off the leading `%` of `%Y` and the trailing `M` of `%M`. The fix took the Org 9.6+ branch via `(org-time-stamp-format t 'no-bracket)` instead.
The new test file has 7 ERT tests across Normal, Boundary, and Error categories. The Error cases assert the output has no stray `%` characters and no literal `Y` in place of the year. I confirmed the same tests fail when I drop in the original buggy implementation, so they catch the bug shape from the report.
|
| |
|
|
|
|
|
|
|
|
| |
I want to track test coverage as I work through the upstream issue backlog, so I added an undercover-based flow that mirrors how `make test-unit` already runs each file in its own Cask Emacs process.
The Makefile gets `make coverage` and `make coverage-clean`. A new helper at `tests/run-coverage-file.el` instruments `org-drill.el` before the source is loaded. Undercover merges per-file results into a single simplecov JSON at `.coverage/simplecov.json`. I added `undercover` as a Cask development dep and `.coverage/` to `.gitignore` so the report stays local.
I also renamed `make install` to `make setup`. The old name read like "deploy the package onto my system," but the target only installs Cask deps into the local `.cask/` directory. `setup` is closer to what it actually does, and all the internal `: install` prerequisites move with it.
Baseline at this commit is 10.8% (208/1928 lines on org-drill.el).
|
| |
|
|
|
|
|
|
| |
The Simple8 failure branch was missing (cl-incf totaln) while SM2 and SM5 both increment total-repeats on failure. After this change, DRILL_TOTAL_REPEATS counts every review attempt regardless of which scheduling algorithm produced it, including failures.
Going-forward only. Historical totaln values for Simple8 failures stay under-counted by one. Correct counting starts with the next failed review.
Paired with the test commit 5c68f1e, which captured the new expected behavior first. Full suite at 214 of 214.
|
| |
|
|
| |
The failure-path assertion in the totaln test now expects the count to increment on both success and failure, matching SM2 and SM5. The updated test goes red against the current source. The source fix follows in the next commit.
|
| |
|
|
|
|
|
|
|
|
| |
The Simple8 algorithm at org-drill-determine-next-interval-simple8 had no direct test coverage, completing the trio after SM2 (37 tests) and SM5 (32 tests, just landed). Adds a per-function test file with 34 tests across Normal, Boundary, Error, algorithm-verification, and helper-specific categories.
Simple8-specific surface gets dedicated coverage. The function returns a 6-element list (not 7 like SM2/SM5) and recomputes ease from meanq each call rather than carrying an EF parameter through. Failure does not increment totaln (different from SM2/SM5, which always increment). The four delta-days configurations (nil, positive × flag, negative × flag) each take a distinct code path, including a late-review use-n adjustment that SM5 doesn't have.
The three pure-math helpers (simple8-first-interval, simple8-interval-factor, simple8-quality->ease) get five direct tests so polynomial-coefficient typos can't drift silently.
All 34 pass on first run as characterization. Full suite at 214 of 214 (was 180, +34).
|
| |
|
|
|
|
|
|
| |
Three test files (SM2, SM5, and the upcoming Simple8) all extract the same fields from a scheduler result list. Pull the shared extractors into tests/testutil-scheduler.el so each algorithm's test file can use them.
Position 2 holds an EF in SM2 and SM5 and an EASE in Simple8. Both names are exposed as aliases pointing at the same nth position so each call site reads accurately.
SM2 and SM5 test files now require testutil-scheduler and call the shared helpers. 69 of 69 scheduler tests still green. Full unit suite at 180 of 180.
|
| |
|
|
|
|
|
|
| |
The SM5 algorithm at org-drill-determine-next-interval-sm5 had no direct test coverage. SM2 has 37 tests. SM5 has zero. Adds a per-function test file that mirrors the SM2 file's structure. 32 tests cover Normal, Boundary, Error, and algorithm-verification categories.
The SM5-specific surface gets dedicated coverage. Failure preserves the input EF, not the modified one. The of-matrix is copied, not mutated. The four delta-days configurations (nil, positive, negative-with-flag, negative-without-flag) each take a different code path. The Error category includes should-error cases for the cl-assert preconditions on n and quality, which is a gap SM2's tests still have.
All 32 pass on first run as characterization. Full suite at 180 of 180.
|
| |
|
|
| |
Add a top note that flags this as a maintained fork with applied upstream patches, and a bottom note clarifying that the existing Author and History sections describe the original project. Helps anyone who lands on the GitHub mirror without context.
|
| |
|
|
| |
The maintenance notes weren't meant to live in public history. Removed from past commits via filter-repo.
|
| |
|
|
| |
The persist package moved to the nongnu ELPA archive years ago. The existing gnu/melpa/org sources couldn't resolve it, so cask install failed and make test-unit was unrunnable. Unblocks the test suite.
|
| |
|
|
| |
(cherry picked from commit eacb6d0c018839d8207ee80e02b46b314278ac3f)
|
| |
|
|
| |
(cherry picked from commit 76d45fb0ea6e216b2cb173bdcf73ef284d350ff8)
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
org-drill-entry-days-since-creation
Wrapped org-time-stamp-to-now call in condition-case to gracefully handle
malformed DATE_ADDED property values. Now returns nil instead of crashing
when encountering invalid timestamp formats.
Changes:
- Added condition-case around org-time-stamp-to-now (lines 2896-2898)
- Returns nil on error, allowing the function to fall through to other
branches or return nil gracefully
This prevents unhandled errors in long-running sessions when drill entries
have corrupted or manually-edited timestamp values.
|
| |
|
|
|
|
|
|
|
|
| |
Changed incorrect property names to match standard naming convention:
- LAST_QUALITY → DRILL_LAST_QUALITY (lines 3394-3395)
- LAST_REVIEWED → DRILL_LAST_REVIEWED (lines 3397-3398)
This ensures consistency with the rest of the codebase where all drill
properties use the DRILL_ prefix. The old names would create properties
that don't match the standard schema and wouldn't be read correctly.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
Created org-drill-lapse-threshold-days defcustom (default 90) to replace
hardcoded values scattered throughout the code. This improves maintainability
and allows users to customize when entries are considered lapsed.
Changes:
- Added defcustom org-drill-lapse-threshold-days (line 660-669)
- Updated org-drill-order-overdue-entries to use variable (line 2867)
- Simplified org-drill--entry-lapsed-p to use variable (line 2884-2886)
- Added safe-local-variable declaration (line 687)
- Updated docstring references to use variable name
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Replaced switch-to-buffer with with-current-buffer to avoid changing
visible buffers during merge operation. This prevents window state
corruption and allows the function to work correctly in batch mode.
Changed line 3374-3375 from:
(save-excursion
(switch-to-buffer (marker-buffer marker))
...)
To:
(with-current-buffer (marker-buffer marker)
(save-excursion
...))
|
| |
|
|
|
|
|
|
| |
Removed commented-out code that redundantly set the failures variable.
The failures count is already obtained from org-drill-entry-failure-count
on line 1538, making the commented code (lines 1548-1550) unnecessary.
This cleans up maintainability issues and removes confusing dead code.
|
| |
|
|
|
|
|
|
|
|
|
| |
Previously used (or (cdr (org-get-property-block)) (point)) which could
return invalid position if no property block exists. Now properly positions
after heading and metadata using org-end-of-meta-data when property block
is missing.
Affects:
- org-drill-present-multicloze-hide-n (line 2267)
- org-drill-present-multicloze-hide-nth (line 2345)
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
Timer cleanup fix:
- Wrapped recursive-edit in unwind-protect to ensure
org-drill-presentation-timer-cancel is always called
- Timer is now cancelled even if recursive-edit exits abnormally
Marker leak fix:
- Moved org-drill-free-markers outside the (unless (oref session end-pos)) condition
- Done-entries markers are now always freed in cleanup, even on error or suspension
- Prevents memory leaks in long-running Emacs sessions
Fixes two severity B bugs in todo.org
|
| |
|
|
|
|
|
| |
Changed 'dasy' to 'days' and improved docstring to follow Emacs conventions
(imperative mood: 'Return non-nil' instead of 'Returns true').
Fixes severity B bug in todo.org
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Added safety counter to prevent infinite loop when all pending entries
are invalid (deleted or no longer have drill tag).
Changes:
- Added attempts counter with max-attempts limit of 1000
- Loop now exits if max attempts reached
- Returns nil if no valid entry found after exhausting attempts
Impact: Prevents infinite loop if all pending entries become invalid,
which could happen if entries are deleted or tags are removed during
a session.
Fixes severity B bug in todo.org
|
| |
|
|
|
|
|
|
|
| |
Added check to ensure last-interval is greater than 0 before performing division.
Impact: Prevents division-by-zero error when last-interval is 0 (new items
or after failures), which would crash the drill session.
Fixes severity B bug in todo.org
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Added fallback to original function when org-get-local-tags doesn't exist.
Changes:
- Removed underscore from orig-fun parameter (now used)
- Added else clause to fallback to (apply orig-fun args)
- Added explanatory comment
Impact: In older org-mode versions where org-get-local-tags doesn't exist,
the function now properly falls back to the original org-get-tags behavior
instead of returning nil, fixing tag functionality.
Fixes severity A bug in todo.org
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Replaced unsafe use of read() function on user-controlled property values
to prevent arbitrary code execution vulnerability.
Changes:
- Lines 1353, 1406: Changed read() to string-to-number() for DRILL_CARD_WEIGHT
- Line 2838: Changed read() to string-to-number() for DRILL_LAST_INTERVAL
- Line 1068: Created org-drill--safe-read-learn-data() helper function that:
* Uses read-from-string instead of read
* Validates input is a list with at least 3 numeric elements
* Returns nil on invalid/malicious input with error handling
* Falls back to safe defaults if LEARN_DATA is corrupted
Impact: Prevents arbitrary code execution if attacker controls org-mode
properties through shared files or malicious imports.
Fixes severity A security bug in todo.org
|
| |
|
|
|
|
|
|
| |
Changed :documementation to :documentation in EIEIO class slot definition.
This fixes EIEIO's ability to recognize slot documentation for introspection
and help systems.
Fixes severity A bug in todo.org
|
| |
|
|
|
|
|
|
| |
Added 66 comprehensive tests covering:
- Entry detection with extreme values and Unicode
- SM2 algorithm with boundary conditions
- Workflow error handling with malformed data
- Card types with complex content structures
|