Non-ASCII characters breaking restore_object()?

In my mudlib, running FluffOS v2019.2020082501, attempts to login with an invalid username will add that username to a mapping in an object. That object is then saved via save_object() and restored via restore_object().

A WWW browser connecting to the mud using SSL/TLS generates several invalid username login attempts involving non-ASCII characters. This data is successfully written to disk via save_object() but a runtime error is generated when restore_object() is called:

restore_object(): Illegal array format while restoring <variable_name>

The data being restored looks like so:

_Log ([ "system": ({ ({ "security", 1605115524, "Login attempt with invalid username, '<non-ASCII characters>' from x.x.x.x", }), }), ])

I believe this is a bug with restore_object().

For testing I split that array out into a series of string variables and tried to restore individual strings instead of an array of strings.

This caused restore_object() to throw the following runtime:

restore_object(): Invalid utf8 string while restoring <variable_name>

could you test if the latest version solve this issue? There are some fixes in master around sanitizing non utf8 inputs and it should have fixed this issue.

Will do. I should have updated and recompiled the driver before I posted, my apologies.

I updated my local FluffOS repos and recompiled. I see no change in behavior; restore_object() still throws a runtime error.

eval return version() returns "fluffos v2019.2020101101-28-g2049d936"

git show displays:

commit 2049d9369efa073a8e915ae7cb4ec7da36f86285 (HEAD -> master, origin/master, origin/HEAD)
Author: Yucong Sun sunyucong@gmail.com
Date: Wed Nov 11 02:21:17 2020 -0800

right, the fix is not generating invalid data during save_variable() . The change won’t help on loading existing bad data files. so can you tests the whole flow if you are still able to create invalid saves?

I did test the whole flow. My process was as follows:

  1. Delete the data file.
  2. Destruct the object.
  3. Load the object so that it creates a new data file. Verify that it all works.
  4. Use a WWW browser to open a TLS connection to the mud. This populates the object with the bogus data and saves that data to file.
  5. Destruct the object.
  6. Load the object.
  7. Observe runtime error from restore_object()

could you tell me how did you manage to put non-utf8 data into the object? is it done through normal command or input_to efuns ?

btw, if you hop over to https://gitter.im/fluffos/community , I’m available to chat real time

The following code demonstrates the error that I see.

The data is retrieved by calling input_to(). The function receiving the data, InputName(), calls “/daemon/restore_object_test”->AddEntry(). This function simply adds the data to an array and then calls save_object().

If I touch the mud with a TLS browser then that array is populated with ugly data. Dest’ing and loading /daemon/restore_object_test then causes restore_object() to throw an error.

/whatever/file/handles/logon()

// Driver Apply
void logon()
{
  receive("Username: ");
  input_to((:InputName:), 2);
}

void InputName(string name)
{
   "/daemon/restore_object_test"->AddEntry(name);
   // ...normal processing happens, prompt for password and such
}

/daemon/restore_object_test.c

string *_Log = ({ });

void create()
{
  restore_object("/tmp/restore_object_test.o"); 
}

void AddEntry(string msg)
{
  _Log += ({ msg });
  save_object("/tmp/restore_object_test.o");
}

I’m having trouble reproducing your result , here is what I did on the latest master build:

string* res = ({ });
nosave object receiver;

void on_input(string item) {
  res += ({ item });
  tell_object(receiver, sprintf("%O", res));
  save_object("/1.o");
  restore_object("/1.o");
  tell_object(receiver, sprintf("%O", res));
}

int main(string arg)
{
  receiver = this_player();
  write("]");
  input_to("on_input", 1);
  return 1;
}

and here is the result, I’m just using chrome to, what websocket client are you using?

any updates?

I am still experiencing this issue. I am not explicitly utilizing WebSockets in my MUD, perhaps that is happening in the backend.

Players login to my MUD by opening a telnet session to mud.dreamverse.org port 9600. The problem I am running into is when an HTTPS session is opened to https://mud.dreamverse.org:9600.

The username, as received by input_to(), is added to to an array. That array is then added to a mapping as the value of the key/value pair. The “username” is the encrypted protocol text from the TLS session. This text is written to file by save_object() without complaint but when it is restored via restore_object() I receive the “Illegal array format while restoring” runtime error.

Do you mean TLS instead of HTTPS? Otherwise how does your mud handle https? Is it through some middle server? Maybe they corrupted the string.

Could you print out the username you received using “sprintf(“%O”, username)”, and the mapping that is supposedly corrupt?

I am trying to pinpoint where did things go wrong.

Ah I think I know what the problem is … driver didn’t properly sanitize the input in telnet cases, that will be fixed, but the gist is that you weren’t actually sending utf8 encoded data.

fix is merged into master