@@ -231,6 +231,35 @@ luaL_remaining_bytes(lua_State *L)
231231 return 1 ;
232232}
233233
234+ /* Returns a random element of specified array. */
235+ static int
236+ luaL_oneof (lua_State *L)
237+ {
238+ lua_userdata_t *lfdp;
239+ lfdp = (lua_userdata_t *)luaL_checkudata (L, 1 , FDP_LUA_UDATA_NAME);
240+ if (!lfdp)
241+ luaL_error (L, " Usage: <FuzzedDataProvider>:oneof(table)" );
242+ luaL_checktype (L, 2 , LUA_TTABLE);
243+
244+ int len = 0 ;
245+ /* Push starting `nil` for iterations. */
246+ lua_pushnil (L);
247+ while (lua_next (L, 2 ) != 0 ) {
248+ /*
249+ * Remove `value` from the stack. Keeps `key` for
250+ * the next iteration.
251+ */
252+ lua_pop (L, 1 );
253+ len++;
254+ }
255+
256+ int idx = lfdp->fdp ->ConsumeIntegralInRange (1 , len);
257+ lua_pushinteger (L, idx);
258+ lua_gettable (L, -2 );
259+
260+ return 1 ;
261+ }
262+
234263static int close (lua_State *L) {
235264 lua_userdata_t *lfdp;
236265 lfdp = (lua_userdata_t *)luaL_checkudata (L, 1 , FDP_LUA_UDATA_NAME);
@@ -256,6 +285,7 @@ const luaL_Reg methods[] =
256285 { " consume_integers" , luaL_consume_integers },
257286 { " consume_probability" , luaL_consume_probability },
258287 { " remaining_bytes" , luaL_remaining_bytes },
288+ { " oneof" , luaL_oneof },
259289 { " __gc" , close },
260290 { " __tostring" , tostring },
261291 { NULL , NULL }
0 commit comments