|
| 26 Mar 2015 09:14 PM |
Let us discuss \000:
print("ABC\000DEF") --> ABC
print(string.gsub("ABCDEF", "\000", "")) --Why does this print the length of my string? --> ABCDEF 7
print(string.gsub("ABC", "\000", "")) --> ABC 4
print(string.gsub("ABC\000DEF", "\000", "")) --> ABC 8
AAAAH! Interdimensional strings!
print(string.match("ABC\000DEF", ".+$")) --> ABC
print(string.match("ABC\000DEF", "[^.]")) --> A
This is so annoying! Is there any way I can get rid of this \000 in a string that I don't want to hunt down, preferably without using string.format("%q", "ABC\000DEF")? It stops the printing of anything after that, and I really really don't want to have to find where this character is coming from.
|
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
| |
|
|
| 26 Mar 2015 09:17 PM |
Uh, thanks. The whole reason I am doing this is FOR Roblox.... But thanks for the advice, I will remember it. |
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
|
| 26 Mar 2015 09:24 PM |
| No, I mean it really is Roblox's fault. Test it on vanilla Lua. |
|
|
| Report Abuse |
|
|
|
| 26 Mar 2015 09:27 PM |
Oh. That might work. Unfortunately, my Lua is probably older than Roblox's. (jk) but I would probably need to download a new one. That's still no problem, but my natural habitat is Roblox.
Oh well, I guess I will just hunt down the string. It will be a pain. It's someone else's code. I still need to use his code though, and I would much rather use it on Roblox than make it compatible with vanilla Lua. |
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
|
| 26 Mar 2015 09:30 PM |
| In regular Lua, \0 doesn't terminate the string but Roblox probably handles it differently. |
|
|
| Report Abuse |
|
|
|
| 26 Mar 2015 09:34 PM |
Very interesting. Also, since you know more about this than me, how long (in bytes) is a Roblox Lua string? |
|
|
| Report Abuse |
|
|
|
| 26 Mar 2015 09:35 PM |
\0 is a null terminator.
If you read the documentation of Lua 5.1's virtual machine, EVERY string has one. It's for bytecode interpretation. REMEMBER your strings are interpreted as constants in the virtual machine BEFORE the code is ran.
Simply do this:
print("ABC\\000234");
The second backslash will not count, as it will escape the null terminator. |
|
|
| Report Abuse |
|
|
|
| 26 Mar 2015 09:40 PM |
Also, @Jarod, I don't know if you knew this already but:
print([[ABC\000235]])
Will also work. Bracketed strings are "literals" and are not affected by special characters. |
|
|
| Report Abuse |
|
|
|
| 26 Mar 2015 09:40 PM |
| Yes but I don't know where the source of the \0 is coming from. Doing a quick search shows it is not in the script. I'm trying to teach myself LASM, you see, so I guess I was bound to come across it eventually, especially while reading other peoples' dump parsers. |
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
|
| 26 Mar 2015 09:42 PM |
Oh he wants to escape the null terminator?
I was just saying in Lua you can do this fine: print("cnt\0kill\0me") and expect it to print all of it (lua_pushlstring).
Here's the quote from lua.org: 'Strings have the usual meaning: a sequence of characters. Lua is eight-bit clean and so strings may contain characters with any numeric value, including embedded zeros. That means that you can store any binary data into a string. Strings in Lua are immutable values. You cannot change a character inside a string, as you may in C; instead, you create a new string with the desired modifications, as in the next example:' |
|
|
| Report Abuse |
|
|
|
| 26 Mar 2015 09:42 PM |
Can you show me the code you're talking about?
Because if you are printing the source of a dumped function, you'll hit a null terminator (\0) after the first 6 bytes, because the first 6 bytes is the version string. |
|
|
| Report Abuse |
|
|
|
| 26 Mar 2015 09:47 PM |
| Sure. I'm sure you understand this better than I do. I understand the concept, but I'm having trouble with some of the bytes. Anyhow, it is in ArbiterOfDeath's "Byte Spy v2.0" model, and the only thing I am using is the module it contains called "Parser". The place it has the null terminator is in "Source Name", which contains the source of the script calling module's returned function. It works just fine, until I want to recursively print out the tables. (And with that many table, I find it necessary) |
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
|
| 26 Mar 2015 09:48 PM |
x = "abc\0d" print(#x, #x:gsub("\0", "")) Works with vanilla Lua, just not with Roblox.
If you really wanna remove all null characters in a roblox lua string you can do: local x = "abc\0d"; local y = ""; for key = 1, #x do local value = x:sub(key, key); if value ~= "\0" then y = y ..value; end end
print(#x, #y) |
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
|
| 26 Mar 2015 09:48 PM |
| Wow I'm getting ninja'd so much :( |
|
|
| Report Abuse |
|
|
|
| 26 Mar 2015 09:52 PM |
"It works just fine, until I want to recursively print out the tables. (And with that many table, I find it necessary)"
I understood everything up until here. What tables? What are they filled with?
Because, yes, you are right. The source name being a string carries a null terminator. |
|
|
| Report Abuse |
|
|
|
| 26 Mar 2015 09:53 PM |
| \0 used to not terminate strings in roblox lua. I remember because I was trying to terminate a string in roblox lua and \0 wouldn't work, so I'm not sure why they added this now. |
|
|
| Report Abuse |
|
|
|
| 26 Mar 2015 09:56 PM |
Well, up until the null terminator, it looks like this.
{ [1] = { [1] = Header, [2] = { [1] = { [1] = Header Signature, [2] = Lua,
}, [2] = { [1] = Version Number, [2] = 81,
}, [3] = { [1] = Format Version, [2] = 0,
}, [4] = { [1] = Endianness Flag, [2] = 1,
}, [5] = { [1] = Size of Int, [2] = 4,
}, [6] = { [1] = Size of Size_T, [2] = 4,
}, [7] = { [1] = Size of Instruction, [2] = 4,
}, [8] = { [1] = Size of LUA_Number, [2] = 8,
}, [9] = { [1] = Integral Flag, [2] = 0,
},
},
}, [2] = { [1] = Function, [2] = { [1] = { [1] = Source Name, [2] = =workspace.Script.Source = _G.Recurse(require(workspace.Parse)(function() print("Hi!") end))
After the null terminator, it also contains opcodes and instructions and stuff, constants, locals, et cetera. |
|
|
| Report Abuse |
|
|
|
| 26 Mar 2015 09:58 PM |
@Jarod
It's simply the output that's being terminated. I assume your printing the values manually via a pairs or ipairs iterator? Just do this on all values which are strings:
print(v:gsub("%z", ""));
It will remove the null terminators. |
|
|
| Report Abuse |
|
|
|
| 26 Mar 2015 10:00 PM |
| It works! Thanks a million! |
|
|
| Report Abuse |
|
|
|
| 26 Mar 2015 10:01 PM |
| I'm glad you posted the header, though. I see your Endian flag is also 1. I am thinking it's 1 across ROBLOX. Which I am hoping for. |
|
|
| Report Abuse |
|
|
|
| 26 Mar 2015 10:05 PM |
| What is this "SizeT" thing, and where did the 4 come from? When I dumped the function, I got 07 instead of 04. |
|
|
| Report Abuse |
|
|
|
| 26 Mar 2015 10:09 PM |
Your Site_T value should be never 07 :\ That wouldn't make sense.
04 = 4 bytes 08 = 8 bytes
It's the length of the value which denotes the length of a string. For instance, in bytecode, the length of an upcoming string is stored as (by default) 4 bytes. After those 4 bytes, the string with the length you found is read out.
|
|
|
| Report Abuse |
|
|
|
| 26 Mar 2015 10:11 PM |
I probably did something wrong, but until I know what I did wrong, here's the header according to my dump.
1B4C7561 ;Header Signature 51 ;Version Number 01 ;Format Version 44 ;Endianness Flag 48 ;Size of Int 07 ;Size of Size_T F0 ;Size of Instruction 00 ;Size of Lua_Number 3D ;Integral Flag |
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
| |
|