History log of /dokuwiki/ (Results 51 – 75 of 10912)
Revision Date Author Comments
(<<< Hide modified files)
(Show modified files >>>)
1bec819726-Jun-2026 splitbrain <86426+splitbrain@users.noreply.github.com>

�� Rector and PHPCS fixes

7930587326-Jun-2026 Andreas Gohr <andi@splitbrain.org>

fix RSS feed aggregation broken by SimplePie 1.9 upgrade

SimplePie 1.9 added a FileClient that rejects any response whose error is
non-null while the status code is zero. FeedParserFile never set a

fix RSS feed aggregation broken by SimplePie 1.9 upgrade

SimplePie 1.9 added a FileClient that rejects any response whose error is
non-null while the status code is zero. FeedParserFile never set a status
code and copied DokuHTTPClient's error verbatim, which is an empty string
(not null) on success - so every successful fetch was misclassified as a
failed request and feeds rendered the 'rssfailed' message.

Populate the response through SimplePie's Response interface methods backed
by our own properties (status code, body, normalized headers, requested URL)
and report a missing error as null, instead of writing File's deprecated
backwards-compatibility properties.

show more ...

946266a326-Jun-2026 Schplurtz le Déboulonné <Schplurtz@laposte.net>

Translation update (fr)

2848662b25-Jun-2026 splitbrain <86426+splitbrain@users.noreply.github.com>

�� Rector and PHPCS fixes

7a48b45e25-Jun-2026 Andreas Gohr <andi@splitbrain.org>

Updated dependencies

884caed925-Jun-2026 Andreas Gohr <gohr@cosmocode.de>

Remote: restrict core.aclCheck for other users to superusers

aclCheck() let any API-enabled user pass an arbitrary username and learn
that user's effective permission level on any page/namespace, en

Remote: restrict core.aclCheck for other users to superusers

aclCheck() let any API-enabled user pass an arbitrary username and learn
that user's effective permission level on any page/namespace, enabling
ACL-posture enumeration of other accounts. Checking another user's
permissions is now limited to superusers; users may still check their
own. The deprecated legacyAclCheck() delegates here and is covered too.

Not really a big security concern, but there is no reason to enable it.

Note: arbitrary groups can still be checked by anyone.

show more ...

40981bcc25-Jun-2026 Andreas Gohr <gohr@cosmocode.de>

Ip: validate CIDR mask to prevent fatal error and over-broad proxy trust

A non-numeric or empty mask in trustedproxies (e.g. 10.0.0.0/abc or
10.0.0.0/) threw an uncaught TypeError on the IPv4 path,

Ip: validate CIDR mask to prevent fatal error and over-broad proxy trust

A non-numeric or empty mask in trustedproxies (e.g. 10.0.0.0/abc or
10.0.0.0/) threw an uncaught TypeError on the IPv4 path, and a negative
mask (10.0.0.0/-1) passed the bounds check and produced a bitmask that
matched every IPv4, silently trusting all proxies.

Validate the mask as a non-negative integer in ipInRange() and broaden
the ipMatches() catch to Throwable so an invalid range degrades to
'no match' instead of a 500.

show more ...

9af8222925-Jun-2026 Andreas Gohr <gohr@cosmocode.de>

extension: validate base name to prevent path traversal on install

The extension base name flowed unsanitized from an uploaded archive's
plugin.info.txt (or an extension id) into getInstallDir(), wh

extension: validate base name to prevent path traversal on install

The extension base name flowed unsanitized from an uploaded archive's
plugin.info.txt (or an extension id) into getInstallDir(), where
fullpath() collapses '..' segments. A crafted base such as
'../../../../evil' therefore resolved outside lib/plugins/, letting
dircopy() write the archive contents to an arbitrary web-writable path.

Route every base assignment through a new setBase() that rejects
anything other than a bare extension name.

Note: this is not really a security concern since plugins can execute
arbitrary code by design. The is mostly to make sure, plugin code is not
installed accidentally at the wrong location.

show more ...

15751e1825-Jun-2026 Andreas Gohr <gohr@cosmocode.de>

Preserve edid and onselect across media manager search (#4608)

The media manager popup search reloads the whole page, dropping the
edid and onselect parameters that plugins (e.g. struct, prosemirror

Preserve edid and onselect across media manager search (#4608)

The media manager popup search reloads the whole page, dropping the
edid and onselect parameters that plugins (e.g. struct, prosemirror)
rely on to insert media and run their callback. Carry them over in the
search form action URL so they survive the reload, and match them in
media.js regardless of their position in the query string.

show more ...

195a3a7f25-Jun-2026 Andreas Gohr <gohr@cosmocode.de>

make getUserData() fail safely on non-string input

When removing multiple users at once, plugins listening on the
AUTH_USER_CHANGE event may pass the array of user names (params[0]
for 'delete') to

make getUserData() fail safely on non-string input

When removing multiple users at once, plugins listening on the
AUTH_USER_CHANGE event may pass the array of user names (params[0]
for 'delete') to getUserData(), which crashed authplain with an
"Array to string conversion" / illegal offset error.

Guard the bundled auth backends so a non-string user fails safely
by returning false, and document that AUTH_USER_CHANGE params[0] is
a string for create/modify but a string[] for delete.

Fixes #4567

show more ...

6436b0ab25-Jun-2026 Schplurtz le Déboulonné <Schplurtz@laposte.net>

Translation update (fr)

a7e1021625-Jun-2026 splitbrain <86426+splitbrain@users.noreply.github.com>

�� Rector and PHPCS fixes

6c7ec05025-Jun-2026 splitbrain <86426+splitbrain@users.noreply.github.com>

�� Update deleted files

75364f1325-Jun-2026 Marek Adamski <fevbew@wp.pl>

Translation update (pl)

43162c2f23-Jun-2026 Andreas Gohr <gohr@cosmocode.de>

Search: give SEARCH_RESULT_FULLPAGE a default action

The fulltext result row is now built by buildPageResultRow(), registered
as the event's default action, so plugins can preventDefault() to render

Search: give SEARCH_RESULT_FULLPAGE a default action

The fulltext result row is now built by buildPageResultRow(), registered
as the event's default action, so plugins can preventDefault() to render
a results differently instead of only amending the row.

The event data gains 'score', 'highlight', a 'showsnippet' flag and a
'class' for the result wrapper. Plugins amending the row must now use the
AFTER hook, since the row no longer exists when BEFORE handlers run.

show more ...

c651c34b17-Jun-2026 Andreas Gohr <gohr@cosmocode.de>

BacklinksTest: give testLinksInDeletedPages its own page

testLinksInDeletedPages reused test:internallinks, the same page
testInternallink already saves and indexes. Since the data dir is
shared acr

BacklinksTest: give testLinksInDeletedPages its own page

testLinksInDeletedPages reused test:internallinks, the same page
testInternallink already saves and indexes. Since the data dir is
shared across the class, when the re-save and the earlier index land
in the same second, needsIndexing() now (correctly) reports the page
as up to date and addPage() skips reindexing, leaving stale link data.
backlinks('test:internallink') then returned an empty array.

Use a dedicated page (test:deletedlinks) with its own link targets so
the test no longer collides with testInternallink's index state.

show more ...

2cda016617-Jun-2026 Andreas Gohr <gohr@cosmocode.de>

Indexer: signal nothing-to-do via boolean return instead of void

The TaskRunner runs indexing, sitemap, digest and changelog-trim tasks
in sequence and relies on each task returning false when it di

Indexer: signal nothing-to-do via boolean return instead of void

The TaskRunner runs indexing, sitemap, digest and changelog-trim tasks
in sequence and relies on each task returning false when it did no work
so the next one is tried. The indexer rewrite changed addPage(),
deletePage() and renamePage() to return void and only abort via
exceptions, breaking that contract: indexing always looked like work was
done and the following tasks never ran.

Restore the boolean return on these three methods (true when work was
done, false when there was nothing to do) while still using exceptions
to signal errors, and propagate it through TaskRunner::runIndexer().
runIndexer() also no longer forces reindexing on every call.

The legacy compatibility layer is adjusted to match: LegacyIndexer and
idx_addPage() forward the boolean, mapping SearchExceptions back to the
historic error-message/false returns. LegacyIndexer::renamePage()
restores the 'page is not in index' message that the move plugin expects.

Closes #4661

show more ...

79dae64d17-Jun-2026 Andreas Gohr <gohr@cosmocode.de>

Indexer: treat same-second save and index as up to date

needsIndexing() compared the .indexed tag mtime against the page mtime
with <=, so a page that was saved and indexed within the same second wa

Indexer: treat same-second save and index as up to date

needsIndexing() compared the .indexed tag mtime against the page mtime
with <=, so a page that was saved and indexed within the same second was
always reported as still needing indexing. Require the page to be
strictly newer than the index tag instead, so an equal mtime correctly
counts as up to date.

show more ...

5d71952d16-Jun-2026 Andreas Gohr <andi@splitbrain.org>

Translation update (de)

f4daad6a13-Jun-2026 Andreas Gohr <andi@splitbrain.org>

AI Policy document added

2ff7e61c10-Jun-2026 Andreas Gohr <gohr@cosmocode.de>

fix(indexer): explicitly handle renames

In an attempt to simplify the index handling, the newly refactored
indexer implemented a rename as delete+add sequence.

This had unintended consequences for

fix(indexer): explicitly handle renames

In an attempt to simplify the index handling, the newly refactored
indexer implemented a rename as delete+add sequence.

This had unintended consequences for the move plugin which may move
several pages at once, requiring a working index even while some pages
have already been moved while others still remain at their old location.

Related to #4646

show more ...

eab6268c07-Jun-2026 Andreas Gohr <andi@splitbrain.org>

fix(changelog): keep out-of-order external edits out of recent changes (#4634)

A detected external edit is recorded both in the page's own changelog and in
the global recent-changes feed. When its d

fix(changelog): keep out-of-order external edits out of recent changes (#4634)

A detected external edit is recorded both in the page's own changelog and in
the global recent-changes feed. When its date is older than the most recent
change already in the global changelog — an old file surfacing after the feed
has moved on — appending it placed it at the top of recent changes with an old
date, above genuinely newer entries.

writeLogEntry() now delegates the global-feed append to writeGlobalLogEntry(),
which skips an external edit whose date predates the global changelog's
last-modified time. The entry still lands in the page's own changelog; it is
only kept out of the cross-page feed. Normal edits are always appended.

show more ...

0a24532907-Jun-2026 Andreas Gohr <andi@splitbrain.org>

fix(changelog): don't record an external edit when the content is unchanged (#4634)

A current revision's file mtime can change without its content changing — a
backup restore, a git checkout, an in-

fix(changelog): don't record an external edit when the content is unchanged (#4634)

A current revision's file mtime can change without its content changing — a
backup restore, a git checkout, an in-place rewrite. Such a bump was detected
as an external edit and logged with a 0-byte size change, cluttering history.

getCurrentRevisionInfo() now compares the current content against the last
recorded revision before treating an mtime change as an external edit. When the
content is identical no external edit happened: the file mtime is reset to the
recorded revision date and the last revision is returned. The comparison is an
abstract currentContentMatchesRevision() — pages compare the decompressed text,
media compare file size then md5_file().

show more ...

2bde879a07-Jun-2026 Andreas Gohr <andi@splitbrain.org>

Fix diff view comparing a deleted page with itself (#4635)

When opening the diff of a deleted page without explicit rev parameters
(?do=diff), Diff::handle() resolved the older side via getRevisions

Fix diff view comparing a deleted page with itself (#4635)

When opening the diff of a deleted page without explicit rev parameters
(?do=diff), Diff::handle() resolved the older side via getRevisions(0, 1).
That helper only skips the current revision when the item file still
exists, so for a deleted page it returned the deletion entry itself and
the view ended up comparing the current revision with itself ("no way to
compare when less than two revisions", empty diff).

Use getRelativeRevision($rev2, -1) instead, which returns the revision
immediately before the current one regardless of whether the page file
is still present. This covers both pages deleted through DokuWiki and
externally deleted pages (whose synthesized deletion entry is now
persisted to the changelog).

Add PageDiffTest and PageChangeLogTest covering the resolved revision
pair and the underlying changelog walk-back for both deletion kinds.

show more ...

c959e5ab07-Jun-2026 splitbrain <86426+splitbrain@users.noreply.github.com>

�� Rector and PHPCS fixes

12345678910>>...437