summaryrefslogtreecommitdiff
path: root/lib9p/idl
diff options
context:
space:
mode:
authorLuke T. Shumaker <lukeshu@lukeshu.com>2025-01-12 21:10:34 -0700
committerLuke T. Shumaker <lukeshu@lukeshu.com>2025-01-14 20:01:31 -0700
commite1994d3d3f2bb80d039d0db567706e0739161e79 (patch)
treed5345e23564d3154b6ecb2abe2781ffbe563a2d1 /lib9p/idl
parent68a9773683ae975f03cac9f327c729b3149f2689 (diff)
lib9p: Limit count and offset to INT{32,64}_MAX
Diffstat (limited to 'lib9p/idl')
-rw-r--r--lib9p/idl/0000-README.md4
-rw-r--r--lib9p/idl/1995-9P1.9p.wip4
-rw-r--r--lib9p/idl/2002-9P2000.9p15
-rw-r--r--lib9p/idl/__init__.py2
4 files changed, 16 insertions, 9 deletions
diff --git a/lib9p/idl/0000-README.md b/lib9p/idl/0000-README.md
index a541006..036de22 100644
--- a/lib9p/idl/0000-README.md
+++ b/lib9p/idl/0000-README.md
@@ -54,6 +54,10 @@ can be
- `&fieldname` to refer to the offset of a field name in that struct,
- the special value `end` to refer to the offset of the end of the
struct,
+ - the special value `s32_max` to refer to the constant value
+ `(1<<31)-1`, or
+ - the special value `s64_max` to refer to the constant value
+ `(1<<63)-1`
A parser for this syntax is given in `__init__.py`. However,
`__init__.py` places the somewhat arbitrary undocumented restrictions
diff --git a/lib9p/idl/1995-9P1.9p.wip b/lib9p/idl/1995-9P1.9p.wip
index 30b9112..4e3a6f5 100644
--- a/lib9p/idl/1995-9P1.9p.wip
+++ b/lib9p/idl/1995-9P1.9p.wip
@@ -1,6 +1,6 @@
# lib9p/idl/1995-9P1.9p - Definitions of 9P1 (Plan 9 2nd ed and 3rd ed) messages
#
-# Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
+# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
# SPDX-License-Identifier: AGPL-3.0-or-later
# https://man.cat-v.org/plan_9_2nd_ed/5/
@@ -38,7 +38,7 @@ msg Topen = "typ[1,val=TODO] tag[tag] fid[fid] mode[1]"
msg Ropen = "typ[1,val=TODO] tag[tag] fid[fid] qid[8]"
msg Tcreate = "typ[1,val=TODO] tag[tag] fid[fid] name[28] perm[4] mode[1]"
msg Rcreate = "typ[1,val=TODO] tag[tag] fid[fid] qid[8]"
-msg Tread = "typ[1,val=TODO] tag[tag] fid[fid] offset[8] count[2,max=8192]"
+msg Tread = "typ[1,val=TODO] tag[tag] fid[fid] offset[8,max=s64_max] count[2,max=8192]"
msg Rread = "typ[1,val=TODO] tag[tag] fid[fid] count[2,max=8192] pad[1] count*(data[1])"
msg Twrite = "typ[1,val=TODO] tag[tag] fid[fid] offset[8] count[2,max=8192] pad[1] count*(data[1])"
msg Rwrite = "typ[1,val=TODO] tag[tag] fid[fid] count[2,max=8192]"
diff --git a/lib9p/idl/2002-9P2000.9p b/lib9p/idl/2002-9P2000.9p
index c83f439..4b0738f 100644
--- a/lib9p/idl/2002-9P2000.9p
+++ b/lib9p/idl/2002-9P2000.9p
@@ -1,6 +1,6 @@
# lib9p/idl/2002-9P2000.9p - Definitions of 9P2000 messages
#
-# Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com>
+# Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
# SPDX-License-Identifier: AGPL-3.0-or-later
# "9P2000" base protocol
@@ -9,11 +9,14 @@
#
# But due to incompleteness of the draft RFC, the Plan 9 manual
# section-5 and the Plan 9 headers (particularly fcall.h) are often
-# better references.
+# better references. The s{32,64}_max limitations are not documented
+# in the draft RFC or the manual pages, but have been enforced by
+# lib9p/srv.c in every release of Plan 9 4e.
#
# https://github.com/plan9foundation/plan9/tree/main/sys/man/5
# https://man.cat-v.org/plan_9/5/
# https://github.com/plan9foundation/plan9/blob/main/sys/include/fcall.h
+# https://github.com/plan9foundation/plan9/blob/main/sys/src/lib9p/srv.c
version "9P2000"
# tag - identify a request/response pair
@@ -22,8 +25,8 @@ num tag = 2
# file identifier - like a UNIX file-descriptor
num fid = 4
-# data - u32le `n`, then `n` bytes of data
-struct d = "len[4] len*(dat[1])"
+# data - s32le `n`, then `n` bytes of data
+struct d = "len[4,max=s32_max] len*(dat[1])"
# string - u16le `n`, then `n` bytes of UTF-8, without any nul-bytes
struct s = "len[2] len*(utf8[1])"
@@ -136,9 +139,9 @@ msg Topen = "size[4,val=end-&size] typ[1,val=112] tag[tag] fid[fid] mode[o]"
msg Ropen = "size[4,val=end-&size] typ[1,val=113] tag[tag] qid[qid] iounit[4]"
msg Tcreate = "size[4,val=end-&size] typ[1,val=114] tag[tag] fid[fid] name[s] perm[dm] mode[o]"
msg Rcreate = "size[4,val=end-&size] typ[1,val=115] tag[tag] qid[qid] iounit[4]"
-msg Tread = "size[4,val=end-&size] typ[1,val=116] tag[tag] fid[fid] offset[8] count[4]"
+msg Tread = "size[4,val=end-&size] typ[1,val=116] tag[tag] fid[fid] offset[8,max=s64_max] count[4,max=s32_max]"
msg Rread = "size[4,val=end-&size] typ[1,val=117] tag[tag] data[d]" # for directories `data` is the sequence "cnt*(entries[stat])"
-msg Twrite = "size[4,val=end-&size] typ[1,val=118] tag[tag] fid[fid] offset[8] data[d]"
+msg Twrite = "size[4,val=end-&size] typ[1,val=118] tag[tag] fid[fid] offset[8,max=s64_max] data[d]"
msg Rwrite = "size[4,val=end-&size] typ[1,val=119] tag[tag] count[4]"
msg Tclunk = "size[4,val=end-&size] typ[1,val=120] tag[tag] fid[fid]"
msg Rclunk = "size[4,val=end-&size] typ[1,val=121] tag[tag]"
diff --git a/lib9p/idl/__init__.py b/lib9p/idl/__init__.py
index 3379bdf..c08a89e 100644
--- a/lib9p/idl/__init__.py
+++ b/lib9p/idl/__init__.py
@@ -447,7 +447,7 @@ def parse_file(
typs: list[Type] = [x for x in env.values() if not isinstance(x, Primitive)]
for typ in [typ for typ in typs if isinstance(typ, Struct)]:
- valid_syms = ["end", *["&" + m.name for m in typ.members]]
+ valid_syms = ["end", "s32_max", "s64_max", *["&" + m.name for m in typ.members]]
for member in typ.members:
for tok in [*member.max.tokens, *member.val.tokens]:
if isinstance(tok, ExprSym) and tok.name not in valid_syms: