Project

General

Profile

Actions

Bug #3279

closed

mod_dirlisting: JS code for mtime parsing is encoding 12 months within only 3 bits

Added by xu.k 20 days ago. Updated 20 days ago.

Status:
Fixed
Priority:
Normal
Category:
mod_dirlisting
Target version:
ASK QUESTIONS IN Forums:
No

Description

https://git.lighttpd.net/lighttpd/lighttpd1.4/src/commit/230a4f53a4d136279a678c4f2cef17fea4f3f2d6/src/mod_dirlisting.c#L759-L764

3 bits (25-22) are not enough to encode 12 months. Currently 2025-Jan is encoded as ((2025<<25) | (0<<22)) i.e. ((2024*8 + 8)<<22), while 2024-Oct is ((2024*8 + 9)<<22), so sorting by mtime will believe 2024-Oct is newer than 2025-Jan.

A quick fix can be change 25 in `parseInt(d0)*(1<<25)` into 26.

diff --git a/src/mod_dirlisting.c b/src/mod_dirlisting.c
index d8baf381..f3de27f0 100644
--- a/src/mod_dirlisting.c
+++ b/src/mod_dirlisting.c
@@ -756,7 +756,7 @@ static const char js_simple_table_resort[] = \
 "    el.dataset.value = -1;\n" \
 "  } else {\n" \
 "   var d = li_date_regex.exec(get_inner_text(el));\n" \
-"   el.dataset.value = (parseInt(d[1])*(1<<25))\n" \
+"   el.dataset.value = (parseInt(d[1])*(1<<26))\n" \
 "     + ( (li_mon_num(d[2])<<22)\n" \
 "        |(parseInt(d[3])  <<17)\n" \
 "        |(parseInt(d[4])  <<12)\n" \

A more advanced fix (and better, IMO) is, why bother tweaking with bit operations instead of just utilizing JS Date class? The calculated mtime can be a reasonable value for some further functionalities if using JS Date.

diff --git a/src/mod_dirlisting.c b/src/mod_dirlisting.c
index d8baf381..55cd28a7 100644
--- a/src/mod_dirlisting.c
+++ b/src/mod_dirlisting.c
@@ -756,12 +756,10 @@ static const char js_simple_table_resort[] = \
 "    el.dataset.value = -1;\n" \
 "  } else {\n" \
 "   var d = li_date_regex.exec(get_inner_text(el));\n" \
-"   el.dataset.value = (parseInt(d[1])*(1<<25))\n" \
-"     + ( (li_mon_num(d[2])<<22)\n" \
-"        |(parseInt(d[3])  <<17)\n" \
-"        |(parseInt(d[4])  <<12)\n" \
-"        |(parseInt(d[5])  << 6)\n" \
-"        |(parseInt(d[6])) );\n" \
+"   el.dataset.value = new Date(\n" \
+"     parseInt(d[1]), li_mon_num(d[2]), parseInt(d[3]),\n" \
+"     parseInt(d[4]), parseInt(d[5]), parseInt(d[6])\n" \
+"   ).getTime() / 1000;\n" \
 "  }\n" \
 " }\n" \
 "}\n" \
Actions #1

Updated by gstrauss 20 days ago

  • Status changed from New to Patch Pending
  • Target version changed from 1.4.xx to 1.4.78

Thank you for the patch. This patch builds on mod_dirlisting fixes in https://github.com/lighttpd/lighttpd1.4/pull/141

A more advanced fix (and better, IMO) is, why bother tweaking with bit operations instead of just utilizing JS Date class?

That would be cleaner code, yes. "Better" is more debatable. Not an excuse or attack: most javascript programmers pretend that both memory and CPU is infinite. The JS Date class is "just a little bit" bloaty.

Actions #2

Updated by gstrauss 20 days ago

  • Status changed from Patch Pending to Fixed
Actions

Also available in: Atom