Pure Erlang implementation of 9p2000 protocol
filesystem fs 9p2000 erlang 9p

Fix bug with invalid device size when encoding stats

hauleth.dev e6dec6f9 6b29b56e

verified
+40 -7
+7 -7
src/e9p_msg.erl
··· 6 6 %% @end 7 7 -module(e9p_msg). 8 8 9 - -export([parse/1, encode/2, encode_stat/1]). 9 + -export([parse/1, encode/2, encode_stat/1, parse_stat/1]). 10 10 11 11 -export_type([tag/0, 12 12 message/0, ··· 166 166 do_parse(Type, Data) -> 167 167 {error, {invalid_message, Type, Data}}. 168 168 169 - parse_stat(<<_Size:2/?int, 170 - Type:2/?int, 169 + parse_stat(<<Type:2/?int, 171 170 Dev:4/?int, 172 171 QID:13/binary, 173 172 Mode:4/?int, ··· 184 183 dev => Dev, 185 184 qid => binary_to_qid(QID), 186 185 mode => Mode, 187 - atime => calendar:system_time_to_universal_time(Atime, seconds), 188 - mtime => calendar:system_time_to_universal_time(Mtime, seconds), 186 + atime => Atime, 187 + mtime => Mtime, 189 188 length => Len, 190 189 name => Name, 191 190 uid => Uid, ··· 285 284 }) -> 286 285 Encoded = [<< 287 286 Type:2/?int, 288 - Dev:2/?int 287 + Dev:4/?int 289 288 >>, 290 289 qid_to_binary(QID), 291 290 <<Mode:4/?int>>, ··· 307 306 [<<Len:?len>> | Data]. 308 307 309 308 binary_to_qid(<<Type:1/?int, Version:4/?int, Path:8/?int>>) -> 310 - #{type => Type, version => Version, path => Path}. 309 + #{type => Type, version => Version, path => Path, state => []}. 311 310 312 311 qid_to_binary(#{type := Type, version := Version, path := Path}) -> 313 312 <<Type:1/?int, Version:4/?int, Path:8/?int>>. 314 313 314 + time_to_encoded_sec(Sec) when is_integer(Sec) -> <<Sec:4/?int>>; 315 315 time_to_encoded_sec(Time) -> 316 316 Sec = calendar:universal_time_to_system_time(Time, [{unit, second}]), 317 317 <<Sec:4/?int>>.
+33
test/e9p_msg_SUITE.erl
··· 1 + % SPDX-FileCopyrightText: 2026 Łukasz Niemier <~@hauleth.dev> 2 + % 3 + % SPDX-License-Identifier: Apache-2.0 4 + 5 + -module(e9p_msg_SUITE). 6 + 7 + -compile(export_all). 8 + 9 + -include("e9p_internal.hrl"). 10 + 11 + -include_lib("stdlib/include/assert.hrl"). 12 + -include_lib("common_test/include/ct.hrl"). 13 + 14 + all() -> [stat_encode_decode]. 15 + 16 + stat_encode_decode(_Conf) -> 17 + Stat = #{ 18 + type => 0, 19 + dev => 0, 20 + qid => e9p:make_qid(directory, 0, 0, []), 21 + mode => 0, 22 + atime => 0, 23 + mtime => 0, 24 + length => 0, 25 + name => <<>>, 26 + uid => <<>>, 27 + gid => <<>>, 28 + muid => <<>> 29 + }, 30 + <<Len:?len, Out:Len/binary>> = iolist_to_binary(e9p_msg:encode_stat(Stat)), 31 + Decoded = e9p_msg:parse_stat(Out), 32 + ?assertEqual({ok, Stat}, Decoded). 33 +