#1498 Fail to download file on FreeBSD

Reporter rim
Owner Zash
Stars ★★ (2)
  • Type-Defect
  • Status-Fixed
  • OpSys-FreeBSD
  • Priority-Medium
  1. rim on

    http.server error Traceback[httpserver]: /usr/local/lib/prosody/modules/mod_http_files.lua:115: bad argument #1 to 'format' (not a non-negative number in proper range) stack traceback: [C]: in function 'format' /usr/local/lib/prosody/modules/mod_http_files.lua:115: in function </usr/local/lib/prosody/modules/mod_http_files.lua:96> (...tail calls...) /usr/local/lib/prosody/util/events.lua:79: in function </usr/local/lib/prosody/util/events.lua:75> (...tail calls...) /usr/local/lib/prosody/net/http/server.lua:248: in function </usr/local/lib/prosody/net/http/server.lua:176> [C]: in function 'xpcall' /usr/local/lib/prosody/net/http/server.lua:108: in function 'process_next' /usr/local/lib/prosody/net/http/server.lua:124: in function 'success_cb' /usr/local/lib/prosody/net/http/parser.lua:177: in function 'feed' /usr/local/lib/prosody/net/http/server.lua:155: in function </usr/local/lib/prosody/net/http/server.lua:154> (...tail calls...) /usr/local/lib/prosody/net/server_select.lua:915: in function </usr/local/lib/prosody/net/server_select.lua:899> [C]: in function 'xpcall' /usr/local/lib/prosody/../../bin/prosody:80: in function 'loop' /usr/local/lib/prosody/../../bin/prosody:90: in main chunk [C]: in ? (a bit older release) Actual code base: https://hg.prosody.im/trunk/file/tip/net/http/files.lua#l83 local etag = ('"%02x-%x-%x-%x"'):format(attr.dev or 0, attr.ino or 0, attr.size or 0, attr.modification or 0); On FreeBSD stat.dev is uint64_t and looks like it is converted to int32_t somewhere in lua or prosody and result is negative. Quick fix: local etag = ('"%02x-%x-%x-%x"'):format(math.abs(attr.dev or 0), attr.ino or 0, attr.size or 0, attr.modification or 0); produces ETag: "78ff00ff-12f9c-2b4548-5e6103f3"

  2. rim on


  3. Zash on

    Thanks for the report That error only seems to exist in Lua 5.2. In Lua 5.1 and Lua 5.3 it happily produces something. Does this mean a similar error would occur if the inode is over 31 bits large, or if the file is created past 2038?

    • tags Status-Accepted OpSys-FreeBSD
  4. rim on

    Probably yes.

  5. twm on

    The "stat" syscall in luafilesystem will return unsigned 64-bit integers for dev, inode, mtime, etc. on 64-bit platforms. However, Lua can't handle these correctly, as all numeric types are stored as signed 64-bit floats internally, resulting in wrong or even negative values in lfs.attributes. In theory this could happen very randomly on filesystems with 64-bit inodes. As a workaround, rather than truncating lfs.attributes thus making the output even more unpredictable, Prosody could generate the etag from attributes that are unlikely to generate overflows, e.g. size and date (at least for now), possibly a hash of the filename. Ultimately this needs to be fixed in luafilesystem, but this is unlikely to happen for Lua 5.1 and Lua 5.2. The behaviour of Lua 5.3 could be different as 5.3 has an internal integer type - I haven't tested this yet (currently running Prosody 0.11.5 on Lua 5.2).

  6. rim on

    As easy way to fix it - etag can be removed. :) Adding inode to etag - bad idea: inode can be changed but file content not, etag must not change in this case. Probably better get ctime, mtime, size and hash it.

  7. Zash on

    Fixed in https://hg.prosody.im/0.11/rev/8f3b87eaec49

    • tags Status-Fixed
    • owner Zash
  8. rim on


New comment

Not published. Used for spam prevention and optional update notifications.