Offroaders123 / NBTify

A library to read and write NBT files on the web!
http://npm.im/nbtify
MIT License
42 stars 5 forks source link

SNBT Escaped Characters #26

Closed Offroaders123 closed 1 year ago

Offroaders123 commented 1 year ago

Discovered the original implementation of SNBT parsing and stringifying that I'm working with from Deno-Minecraft wasn't set up to handle special escaped characters. I tried implementing a fix for it tonight, but I don't know how I can add it to the parse side of things. I got it working on the stringifying side at least though!

Found some helpful docs about the SNBT format here. Also found a helpful Stack Overflow page that shows how to 'escape escape characters', haha.

quartz_nbt::snbt - Rust Escape new lines with JS - Stack Overflow

And within the SNBTWriter.#writeString() method, this is the code that I wrote that appeared to consistently fix the stringifying portion:

declare let quotedString: string;

const escapedString = quotedString
  .replace(/\n/g,"\\n")
  .replace(/\r/g,"\\r")
  .replace(/\t/g,"\\t");
Offroaders123 commented 1 year ago

Another thing to mention. The current implementation appears to handle seeing these raw special characters when in the SNBT's strings itself, but this isn't expected behavior for it to be able to parse these. It shouldn't be able to parse these. By that, I mean that an unescaped new line shouldn't be expected when inside of a plain "" or '' string, that's not intended behavior. It is good that it currently handles this issue correctly both ways though, which is a relief. So if your SNBT string values have any new lines in them, then it will be able to go back and forth no problem at the moment at least.

I noticed this when reading my demo level.dat file, as it has a new line character at the end of the FlatWorldLayers entry value, and it's showing up as an actual new line character in the editor, rather than an explicit \n character. I initially thought it was an indentation error within the stringifying code, but then I figured out that the entry value there has a new line at the end of it, which clued me in to figuring out that it currently isn't set up to handle those special characters yet.

{
  BiomeOverride: "",
  CenterMapsToOrigin: 0b,
  ConfirmedPlatformLockedContent: 0b,
  Difficulty: 2,
  FlatWorldLayers: '{"biome_id":1,"block_layers":[{"block_name":"minecraft:bedrock","count":1},{"block_name":"minecraft:dirt","count":2},{"block_name":"minecraft:grass","count":1}],"encoding_version":5,"structure_options":null}
',
  ForceGameType: 0b,
  GameType: 0
}
Offroaders123 commented 1 year ago

Looks like these are the characters that it should probably look for to escape, depending on the string literal type.

The following characters are reserved in JSON and must be properly escaped to be used in strings:

Backspace is replaced with \b Form feed is replaced with \f Newline is replaced with \n Carriage return is replaced with \r Tab is replaced with \t Double quote is replaced with \" Backslash is replaced with \\

For SNBT, ' will have to be escaped depending on the string literal, and vice-versa for " in other instances.

Offroaders123 commented 1 year ago

Forgot to reference this issue in the latest commits/update.

1.69.420 (lol)

Offroaders123 commented 1 year ago

Things appear to be stable as of all the work I've done after implementing these changes, so I think I'll mark this as complete! If any new issues arise around this which haven't been discovered yet, I'll reopen this one.