GWR
GWR

Reputation: 2008

JSON Encode string literal "asdf\\nsedfgs"

I am working with an old classic asp/vbscript app that has a json class.

I have a string literal: asdf\\nsedfgs e.g. thats not escaped json or anything. its literally those characters.

So, to use that value in a JSON string, it should be something like this, right?

{"somedesc":"asdf\\\\nsedfgs"}

...with the two backslash characters escaped.

However, on the way out of JSON and back to string literal, we'd do something like this (in this order)

val = Replace(val, "\""", """")
val = Replace(val, "\\", "\")
val = Replace(val, "\/", "/") 
val = Replace(val, "\b", Chr(8))
val = Replace(val, "\f", Chr(12))
val = Replace(val, "\n", Chr(10))
val = Replace(val, "\r", Chr(13))
val = Replace(val, "\t", Chr(9))

...but for the string above, this sequence of replace() gives us the incorrect decoded value:

result (note the newline, as the 4 \ got replaced to two, then the \n got replaced to a newline)

asdf\
sedfgs

So questions:

  1. how does one encode and decode a literal asdf\\nsedfgs to and from json correctly?
  2. is that decode logic correct? in the correct order? It seems not, because how could it distinguish between a literal \n vs an escaped chr(13)?
  3. is there something else I am missing here?

Upvotes: 1

Views: 778

Answers (1)

user6836841
user6836841

Reputation:

The important part is isolating the escaped backslashes from the rest of the string so that they don't interfere with escape sequences- You can split the string, reattach the missing parts later:

Const ENCODE = FALSE
Const DECODE = TRUE

val = "asdf\\\\nsedfgs"
val = JSON(val, DECODE)
MsgBox val

'Swap replacement values & dividers + concatenation characters
val = JSON(val, ENCODE)
MsgBox val

Function JSON(ByVal str, ByVal mode)
    Dim key, val
    Set d = CreateObject("Scripting.Dictionary")

    d.Add "\/", "/"
    d.Add "\b", Chr(8)
    d.Add "\f", Chr(12)
    d.Add "\n", Chr(10)
    d.Add "\r", Chr(13)
    d.Add "\t", Chr(9)

    If mode Then
        d.Add "\""", """"
        d.Add "\\", "\"
        div = "\\"
        cat = "\"
        key = d.Keys
        val = d.Items
    Else
        d.Add "\\", "\"
        d.Add "\""", """"
        div = "\"
        cat = "\\"
        key = d.Items
        val = d.Keys
    End If

    arr = Split(str, div)

    For i = 0 To UBound(arr)
        For j = 0 To UBound(key)
            arr(i) = Replace(arr(i), key(j), val(j))
        Next

        output = output & arr(i)
        If i <> UBound(arr) Then output = output & cat
    Next

    d.RemoveAll
    JSON = output
End Function

Upvotes: 1

Related Questions