Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions changes-entries/66182.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*) mod_autoindex: Fix a FancyIndexing listing sorted by last-modified
date (?C=M) showing 1970-01-01 for files modified before 1970,
instead of their real date. PR 66182 [Arturo Bernal]
9 changes: 2 additions & 7 deletions modules/generators/mod_autoindex.c
Original file line number Diff line number Diff line change
Expand Up @@ -1416,14 +1416,9 @@ static struct ent *make_autoindex_entry(const apr_finfo_t *dirent,
}
ap_destroy_sub_req(rr);
/*
* We don't need to take any special action for the file size key.
* If we did, it would go here.
* We don't need to take any special action for the file size or
* last-modified keys. If we did, it would go here.
*/
if (keyid == K_LAST_MOD) {
if (p->lm < 0) {
p->lm = 0;
}
}
return (p);
}

Expand Down
37 changes: 37 additions & 0 deletions test/modules/generators/test_002_autoindex.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import calendar
import os
import textwrap

import pytest

from pyhttpd.conf import HttpdConf

# A modification time before the 1970 epoch, to check that mod_autoindex
# does not clamp it when sorting by last-modified (BZ 66182).
OLD_MTIME = calendar.timegm((1958, 1, 1, 0, 0, 0, 0, 0, 0))


class TestAutoindex:

Expand All @@ -17,11 +23,23 @@ def _class_scope(self, env):
Options +Indexes
IndexOptions FancyIndexing ScanHTMLTitles
</Directory>
<Directory "{env.server_docs_dir}/autoindex/oldmtime">
Options +Indexes
IndexOptions FancyIndexing
</Directory>
"""),
})
conf.add_vhost(domains=[domain], port=env.http_port,
doc_root="htdocs/autoindex")
conf.install()

oldmtime_dir = os.path.join(env.server_docs_dir, "autoindex", "oldmtime")
os.makedirs(oldmtime_dir, exist_ok=True)
oldfile = os.path.join(oldmtime_dir, "oldfile.txt")
with open(oldfile, "w") as f:
f.write("old file\n")
os.utime(oldfile, (OLD_MTIME, OLD_MTIME))

assert env.apache_restart() == 0

def test_generators_002_01_scan_title_bare_amp(self, env):
Expand All @@ -32,3 +50,22 @@ def test_generators_002_01_scan_title_bare_amp(self, env):
r = env.curl_get(env.mkurl("http", "autoindex", "/listing/"))
assert r.response["status"] == 200
assert "AT&T" in r.response["body"].decode()

def test_generators_002_02_old_mtime_not_clamped_when_sorted(self, env):
"""A file modified before 1970 keeps its real date when the listing
is explicitly sorted by last-modified (?C=M). Before the fix,
make_autoindex_entry() clamped any negative apr_time_t to 0 when
keyid == K_LAST_MOD, displaying 1970-01-01 instead of the real
1958 date -- even though the unsorted, default-order listing (which
does not hit that code path) already showed it correctly."""
unsorted = env.curl_get(env.mkurl("http", "autoindex", "/oldmtime/"))
assert unsorted.response["status"] == 200
unsorted_body = unsorted.response["body"].decode()
assert "1958-01-01" in unsorted_body

sorted_by_date = env.curl_get(
env.mkurl("http", "autoindex", "/oldmtime/?C=M;O=A"))
assert sorted_by_date.response["status"] == 200
sorted_body = sorted_by_date.response["body"].decode()
assert "1958-01-01" in sorted_body
assert "1970-01-01" not in sorted_body
Loading