Skip to content

Commit

Permalink
Truncate very long action to avoid buffer overflow.
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcCote committed Oct 15, 2024
1 parent 5bcf3a8 commit 711c1ba
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 1 deletion.
19 changes: 18 additions & 1 deletion jericho/jericho.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
JERICHO_PATH = importlib.resources.files("jericho")
FROTZ_LIB_PATH = os.path.join(JERICHO_PATH, 'libfrotz.so')

# The buffer size for actions in frotz. -2 to allow for newline and null terminator.
INPUT_BUFFER_SIZE = 200 - 2

# Function to unload a shared library.
dlclose_func = CDLL(None).dlclose # This WON'T work on Win
dlclose_func.argtypes = [c_void_p]
Expand Down Expand Up @@ -361,6 +364,10 @@ class UnsupportedGameWarning(UserWarning):
pass


class TruncatedInputActionWarning(UserWarning):
pass


class FrotzEnv():
"""
The Frotz Environment is a fast interface to Z-Machine games.
Expand Down Expand Up @@ -465,9 +472,19 @@ def step(self, action):
the immediate reward, a boolean indicating whether the game is over,\
and a dictionary of info.
:rtype: string, float, boolean, dictionary
Note:
- The action is converted to bytes and truncated to 198 characters.
'''
action_bytes = action.encode('utf-8')
if len(action_bytes) > INPUT_BUFFER_SIZE:
action_bytes = action_bytes[:INPUT_BUFFER_SIZE]
msg = ("Once converted to bytes, actions should have less than 198 characters."
" Action '{}' was truncated to '{}'.".format(action, action_bytes.decode()))
warnings.warn(msg, TruncatedInputActionWarning)

old_score = self.frotz_lib.get_score()
next_state = self.frotz_lib.step((action+'\n').encode('utf-8')).decode('cp1252')
next_state = self.frotz_lib.step(action_bytes + b'\n').decode('cp1252')
score = self.frotz_lib.get_score()
reward = score - old_score
return next_state, reward, (self.game_over() or self.victory()),\
Expand Down
16 changes: 16 additions & 0 deletions tests/test_jericho.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,19 @@ def test_saving_opcode_in_state():
else:
obs, rew, done, info = env.step(cmd)
assert not env._emulator_halted()


def test_very_long_action():
rom = pjoin(DATA_PATH, "905.z5")
env = jericho.FrotzEnv(rom)
env.reset()

long_command = "It's a " + "very " * 36 + "long action!"
assert len(long_command) == 199
env.step(long_command)
env.step(long_command * 2)

long_command = "It's a " + "très " * 36 + "long action!"
assert len(long_command) == 199
env.step(long_command)
env.step(long_command * 2)

0 comments on commit 711c1ba

Please sign in to comment.