aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThijs Schreijer <thijs@thijsschreijer.nl>2026-02-13 15:07:37 +0100
committerThijs Schreijer <thijs@thijsschreijer.nl>2026-02-13 15:07:37 +0100
commita5ffa54ee71c9819fc413fdf118774b1db21a1df (patch)
tree4072ed7df7c89395386074acfd45f8e47e59c8a6
parentf6f0c77995fcd62863a7f24cbb407a68d2277759 (diff)
downloadluasystem-a5ffa54ee71c9819fc413fdf118774b1db21a1df.tar.gz
luasystem-a5ffa54ee71c9819fc413fdf118774b1db21a1df.tar.bz2
luasystem-a5ffa54ee71c9819fc413fdf118774b1db21a1df.zip
align error handling
-rw-r--r--spec/02-random_spec.lua27
-rw-r--r--src/random.c24
2 files changed, 23 insertions, 28 deletions
diff --git a/spec/02-random_spec.lua b/spec/02-random_spec.lua
index db5d5ce..7b2eea6 100644
--- a/spec/02-random_spec.lua
+++ b/spec/02-random_spec.lua
@@ -155,24 +155,27 @@ describe("Random:", function()
155 end) 155 end)
156 156
157 157
158 it("returns nil and error for empty interval (m > n)", function() 158 it("throws for empty interval (m > n), like math.random", function()
159 local v, err = system.rnd(10, 5) 159 local ok_math, _ = pcall(math.random, 10, 5)
160 assert.is_falsy(v) 160 assert.is_falsy(ok_math, "math.random(10, 5) should error")
161 assert.are.equal("interval is empty", err) 161 local ok_rnd, _ = pcall(system.rnd, 10, 5)
162 assert.is_falsy(ok_rnd, "rnd(10, 5) should throw like math.random")
162 end) 163 end)
163 164
164 165
165 it("returns nil and error for invalid one-arg (m < 1, m ~= 0)", function() 166 it("throws for invalid one-arg (m < 1, m ~= 0), like math.random", function()
166 local v, err = system.rnd(-1) 167 local ok_math, _ = pcall(math.random, -1)
167 assert.is_falsy(v) 168 assert.is_falsy(ok_math, "math.random(-1) should error")
168 assert.are.equal("interval is empty", err) 169 local ok_rnd, _ = pcall(system.rnd, -1)
170 assert.is_falsy(ok_rnd, "rnd(-1) should throw like math.random")
169 end) 171 end)
170 172
171 173
172 it("returns nil and error for wrong number of arguments", function() 174 it("throws for wrong number of arguments, like math.random", function()
173 local v, err = system.rnd(1, 2, 3) 175 local ok_math, _ = pcall(math.random, 1, 2, 3)
174 assert.is_falsy(v) 176 assert.is_falsy(ok_math, "math.random(1, 2, 3) should error")
175 assert.are.equal("wrong number of arguments", err) 177 local ok_rnd, _ = pcall(system.rnd, 1, 2, 3)
178 assert.is_falsy(ok_rnd, "rnd(1, 2, 3) should throw like math.random")
176 end) 179 end)
177 180
178 end) 181 end)
diff --git a/src/random.c b/src/random.c
index 6b09a55..33a640a 100644
--- a/src/random.c
+++ b/src/random.c
@@ -126,8 +126,10 @@ static int lua_get_random_bytes(lua_State* L) {
126/* Read 8 bytes into *out; return 0 on success, 2 on error (nil + msg pushed). */ 126/* Read 8 bytes into *out; return 0 on success, 2 on error (nil + msg pushed). */
127static int read_u64(lua_State *L, uint64_t *out) { 127static int read_u64(lua_State *L, uint64_t *out) {
128 unsigned char buf[8]; 128 unsigned char buf[8];
129
129 int ret = fill_random_bytes(L, buf, 8); 130 int ret = fill_random_bytes(L, buf, 8);
130 if (ret != 0) return ret; 131 if (ret != 0) return ret;
132
131 *out = (uint64_t)buf[0] | ((uint64_t)buf[1] << 8) | ((uint64_t)buf[2] << 16) | 133 *out = (uint64_t)buf[0] | ((uint64_t)buf[1] << 8) | ((uint64_t)buf[2] << 16) |
132 ((uint64_t)buf[3] << 24) | ((uint64_t)buf[4] << 32) | ((uint64_t)buf[5] << 40) | 134 ((uint64_t)buf[3] << 24) | ((uint64_t)buf[4] << 32) | ((uint64_t)buf[5] << 40) |
133 ((uint64_t)buf[6] << 48) | ((uint64_t)buf[7] << 56); 135 ((uint64_t)buf[6] << 48) | ((uint64_t)buf[7] << 56);
@@ -162,13 +164,11 @@ Random number mimicking Lua 5.4 math.random, using crypto-secure bytes.
162- One arg 0: returns a full-range random integer (whole lua_Integer range). 164- One arg 0: returns a full-range random integer (whole lua_Integer range).
163- One arg m (m >= 1): returns an integer in [1, m] (inclusive). 165- One arg m (m >= 1): returns an integer in [1, m] (inclusive).
164- Two args m, n: returns an integer in [m, n] (inclusive). 166- Two args m, n: returns an integer in [m, n] (inclusive).
165On invalid arguments returns nil and an error message. 167On invalid arguments throws an error (same as math.random).
166@function rnd 168@function rnd
167@tparam[opt] int m upper bound (or 0 for full-range), or lower bound when used with n 169@tparam[opt] int m upper bound (or 0 for full-range), or lower bound when used with n
168@tparam[opt] int n upper bound (when used with m) 170@tparam[opt] int n upper bound (when used with m)
169@treturn[1] number|int float in [0,1) or integer in the requested range 171@treturn number|int float in [0,1) or integer in the requested range
170@treturn[2] nil
171@treturn[2] string error message
172*/ 172*/
173static int lua_rnd(lua_State *L) { 173static int lua_rnd(lua_State *L) {
174 int nargs = lua_gettop(L); 174 int nargs = lua_gettop(L);
@@ -210,9 +210,7 @@ static int lua_rnd(lua_State *L) {
210 return 1; 210 return 1;
211 } 211 }
212 if (m < 1) { 212 if (m < 1) {
213 lua_pushnil(L); 213 return luaL_error(L, "interval is empty");
214 lua_pushstring(L, "interval is empty");
215 return 2;
216 } 214 }
217 /* [1, m] -> range size m, values 0..m-1 then +1 */ 215 /* [1, m] -> range size m, values 0..m-1 then +1 */
218 { 216 {
@@ -234,15 +232,11 @@ static int lua_rnd(lua_State *L) {
234 RND_INT low = RND_CHECKINT(L, 1); 232 RND_INT low = RND_CHECKINT(L, 1);
235 RND_INT up = RND_CHECKINT(L, 2); 233 RND_INT up = RND_CHECKINT(L, 2);
236 if (low > up) { 234 if (low > up) {
237 lua_pushnil(L); 235 return luaL_error(L, "interval is empty");
238 lua_pushstring(L, "interval is empty");
239 return 2;
240 } 236 }
241#if LUA_VERSION_NUM >= 503 237#if LUA_VERSION_NUM >= 503
242 if (low < 0 && up > 0 && (lua_Unsigned)(up - low) > (lua_Unsigned)LUA_MAXINTEGER) { 238 if (low < 0 && up > 0 && (lua_Unsigned)(up - low) > (lua_Unsigned)LUA_MAXINTEGER) {
243 lua_pushnil(L); 239 return luaL_error(L, "interval too large");
244 lua_pushstring(L, "interval too large");
245 return 2;
246 } 240 }
247#endif 241#endif
248 { 242 {
@@ -261,9 +255,7 @@ static int lua_rnd(lua_State *L) {
261 } 255 }
262 } 256 }
263 257
264 lua_pushnil(L); 258 return luaL_error(L, "wrong number of arguments");
265 lua_pushliteral(L, "wrong number of arguments");
266 return 2;
267 259
268#undef RND_INT 260#undef RND_INT
269#undef RND_CHECKINT 261#undef RND_CHECKINT