Switch off UTF escaping in JsonBuilder - json

I'm trying to use JsonBuilder in groovy servlet (extending HttpServlet)
Here is a snippet:
public void doGet(HttpServletRequest request, HttpServletResponse response) {
response.setContentType('text/plain')
response.setCharacterEncoding('utf-8')
def pw = response.getWriter()
pw.println(new JsonBuilder(['city': 'Москва']))
pw.println([сity: 'Москва'])
}
The output is
{"city":"\u041C\u043E\u0441\u043A\u0432\u0430"}
{сity=Москва}
I just don't know nothing about UTF escaping in JsonBuilder, googling also did not give my anything valuable. So I guess I'm stuck.
Does anybody know how to get the output for json exactly in same form as we get the output for regular groovy object?

I have encountered the same issue, and the above methods didn't work.
However this did:
http://groovy.codehaus.org/gapi/groovy/json/StringEscapeUtils.html
StringEscapeUtils.unescapeJavaScript(JsonOutput.toJson('Москва'))

As far as JavaScript and/or JSON goes, it is the exact same output.
You can easily confirm this yourself:
'Москва' == '\u041c\u043e\u0441\u043a\u0432\u0430'; // true
What you're seeing are Unicode string escape sequences, which are defined by the ECMAScript specification (JavaScript) and are allowed in JSON as well.
That said, I wouldn't worry about it too much, but if you insist on disabling the string escapes, you can use the JsonOutput object:
JsonOutput.prettyPrint(json.toString());

I've found it, I've found it.
So if you are as stubborn as me and don't want to recognize that (in a very wide range of applications) escaped sequence is exactly the same as non-escape, you can just use JsonOuput object, which is in the same standard package, groovy.xml.*:
JsonOutput.prettyPrint(json.toString())
If somebody's answer will be more detailed, I will delete my own answer and will mark the other answer as accepted. So I encourage you )))

Related

Spring REST - String Serialization - bug or feature?

I found a very strange behavior in spring rest.
Having an endpoint like the following
#GetMapping("/foo")
public String foo() {
return "bar";
}
returns the value bar. Sounds correct, but this is not a valid json, the effective result should be "bar" (note the ""). One might argue that spring expects that if a method returns a string, you have already manually serialized the object, but if all other objects are serialized by spring, then i would expect to have a special way to tell that its already serialized but the default way should be to serialize the value.
Maybe i'm missing something here, that's the reason why i didn't created a ticket in the spring issue tracker jet.
Unregistering the StringHttpMessageConverter as described in this answer should do the trick: https://stackoverflow.com/a/37906098/505621
While not really an answer, there are 2 possible workarounds:
Encode it yourself
Just add the required quotation mark explicitly to the response string \".
This could for example be done by using JSONObject.quote(yourString).
Wrapping
Wrap your string into a simple object or custom class. Then Jackson knows what to do with it.
Collections.singletonMap("value", yourString);

What's the easiest way to convert a 'pretty printed' JSON string to a compact format representation?

This may be an odd question as it's specific to the JSON strings themselves, not the objects they represent. Given a 'pretty printed' JSON string (representing any JSON-encodable model), how would one reformat it to the 'compact' format?
My first thought was to not consider it JSON, but rather just a string, then use RegEx to remove duplicate spaces, remove newlines, etc., but that's not context aware so it risks affecting the keys and values portions of the JSON if you don't properly test that you're inside quotes.
My next thought was to try and construct an object from the JSON, but without a type to convert to, I'm not sure how to do that without manually parsing the values as 'ANY', then testing if they're an array, and recurse into it if they are, repeating the process. Then once I have the final object, serialize the result in compact form. However, that seems like a lot of overkill.
Is there an easier way to accomplish this? We're using Swift 4 if it helps.
UPDATE:
as pointed by #Mark A. Donohoe, this removes ALL whitespaces. so even though it looks coooooool, it's a dumb answer. don't fall for it.
i needed the same thing and i ended up creating a String extension:
extension String {
func toCompactJSON() -> String {
self.filter { !$0.isWhitespace && !$0.isNewline }
}
}
in my case though it was for testing purposes and it turned out to be useless as the order in which the Javascript object/arrays appear is not the same as while generated through the JSONEncoder.

Using Freepascal\Lazarus JSON Libraries

I'm hoping for a bit of a "simpletons" demo\explanation for using Lazarus\Freepascal JSON parsing. I've asked a question here but all the replies are "read this" and none of them are really helping me get a grasp because the examples are bit too in-depth and I'm seeking a very simple example to help me understand how it works.
In brief, my program reads an untyped binary file in chunks of 4096 bytes. The raw data then gets converted to ASCII and stored in a string. It then goes through the variable looking for certain patterns, which, it turned out, are JSON data structures. I've currently coded the parsing the hard way using Pos and ExtractANSIString etc. But I'vesince learnt that there are JSON libraries for Lazarus & FPC, namely fcl-json, fpjson, jsonparser, jsonscanner etc.
https://bitbucket.org/reiniero/fpctwit/src
http://fossies.org/unix/misc/fpcbuild-2.6.0.tar.gz:a/fpcbuild-2.6.0/fpcsrc/packages/fcl-json/src/
http://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/packages/fcl-json/examples/
However, I still can't quite work out HOW I read my string variable and parse it for JSON data and then access those JSON structures.
Can anyone give me a very simple example, to help getting me going?
My code so far (without JSON) is something like this:
try
SourceFile.Position := 0;
while TotalBytesRead < SourceFile.Size do
begin
BytesRead := SourceFile.Read(Buffer,sizeof(Buffer));
inc(TotalBytesRead, BytesRead);
StringContent := StripNonAsciiExceptCRLF(Buffer); // A custom function to strip out binary garbage leaving just ASCII readable text
if Pos('MySearchValue', StringContent) > 0 then
begin
// Do the parsing. This is where I need to do the JSON stuff
...
See parsedemo.pp, specially parsestring. Just modify the doparse routine to extract whatever information you need from the j:TJSonData object.
The simpledemo.pp demonstrates how to disect a jsondata object.
Then read the src/README.txt file. It seems to hint on a bunch of properties of a jsonobject that allow to get fields by name. This only works for structures json objects like array and object.
I do agree that a demo for that would be a good thing. If you make it, please submit it to mantis.
Disclaimer: I have nothing to do with the json package, I got the above from a quick glance at the (admittedly 2.7.1) source.

How can one prevent double encoding of html entities when they are allowed in the input

How can I prevent double encoding of html entities, or fix them programmatically?
I am using the encode() function from the HTML::Entities perl module to encode HTML entities in user input. The problem here is that we also allow users to input HTML entities directly and these entities end up being double encoded.
For example, a user may enter:
Stackoverflow & Perl = Awesome…
This ends up being encoded to
Stackoverflow & Perl = Awesome&hellip;
This renders in the browser as
Stackoverflow & Perl = Awesome…
We want this to render as
Stackoverflow & Perl = Awesome...
Is there a way to prevent this double encoding? Or is there a module or snippet of code that can easily correct these double encoding issues?
Any help is greatly appreciated!
You can decode the string first:
my $input = from_user();
my $encoded = encode_entities( decode_entities $input );
There is an extremely simple way to avoid this:
Remove all the entities upon input (turn them into Unicode)
Encode into entities again at the stage of output.
Consider saving the call to encode() until you retrieve the value for display, rather than before you store it. So long as you are consistent in your retrieval mechanism, the extra data in your database probably isn't worth fretting over.
Edit
Re-reading your question I realize now my answer doesn't fully address the issue seeing as calling encode() later will still have the same results. Not knowing of an alternative myself, it may not be much help, but you may want to consider finding a more suitable method for encoding that will respect existing symbols.

Is it valid to define functions in JSON results?

Part of a website's JSON response had this (... added for context):
{..., now:function(){return(new Date).getTime()}, ...}
Is adding anonymous functions to JSON valid? I would expect each time you access 'time' to return a different value.
No.
JSON is purely meant to be a data description language. As noted on http://www.json.org, it is a "lightweight data-interchange format." - not a programming language.
Per http://en.wikipedia.org/wiki/JSON, the "basic types" supported are:
Number (integer, real, or floating
point)
String (double-quoted Unicode
with backslash escaping)
Boolean
(true and false)
Array (an ordered
sequence of values, comma-separated
and enclosed in square brackets)
Object (collection of key:value
pairs, comma-separated and enclosed
in curly braces)
null
The problem is that JSON as a data definition language evolved out of JSON as a JavaScript Object Notation. Since Javascript supports eval on JSON, it is legitimate to put JSON code inside JSON (in that use-case). If you're using JSON to pass data remotely, then I would say it is bad practice to put methods in the JSON because you may not have modeled your client-server interaction well. And, further, when wishing to use JSON as a data description language I would say you could get yourself into trouble by embedding methods because some JSON parsers were written with only data description in mind and may not support method definitions in the structure.
Wikipedia JSON entry makes a good case for not including methods in JSON, citing security concerns:
Unless you absolutely trust the source of the text, and you have a need to parse and accept text that is not strictly JSON compliant, you should avoid eval() and use JSON.parse() or another JSON specific parser instead. A JSON parser will recognize only JSON text and will reject other text, which could contain malevolent JavaScript. In browsers that provide native JSON support, JSON parsers are also much faster than eval. It is expected that native JSON support will be included in the next ECMAScript standard.
Let's quote one of the spec's - https://www.rfc-editor.org/rfc/rfc7159#section-12
The The JavaScript Object Notation (JSON) Data Interchange Format Specification states:
JSON is a subset of JavaScript but excludes assignment and invocation.
Since JSON's syntax is borrowed from JavaScript, it is possible to
use that language's "eval()" function to parse JSON texts. This
generally constitutes an unacceptable security risk, since the text
could contain executable code along with data declarations. The same
consideration applies to the use of eval()-like functions in any
other programming language in which JSON texts conform to that
language's syntax.
So all answers which state, that functions are not part of the JSON standard are correct.
The official answer is: No, it is not valid to define functions in JSON results!
The answer could be yes, because "code is data" and "data is code".
Even if JSON is used as a language independent data serialization format, a tunneling of "code" through other types will work.
A JSON string might be used to pass a JS function to the client-side browser for execution.
[{"data":[["1","2"],["3","4"]],"aFunction":"function(){return \"foo bar\";}"}]
This leads to question's like: How to "https://stackoverflow.com/questions/939326/execute-javascript-code-stored-as-a-string".
Be prepared, to raise your "eval() is evil" flag and stick your "do not tunnel functions through JSON" flag next to it.
It is not standard as far as I know. A quick look at http://json.org/ confirms this.
Nope, definitely not.
If you use a decent JSON serializer, it won't let you serialize a function like that. It's a valid OBJECT, but not valid JSON. Whatever that website's intent, it's not sending valid JSON.
JSON explicitly excludes functions because it isn't meant to be a JavaScript-only data
structure (despite the JS in the name).
A short answer is NO...
JSON is a text format that is completely language independent but uses
conventions that are familiar to programmers of the C-family of
languages, including C, C++, C#, Java, JavaScript, Perl, Python, and
many others. These properties make JSON an ideal data-interchange
language.
Look at the reason why:
When exchanging data between a browser and a server, the data can only
be text.
JSON is text, and we can convert any JavaScript object into JSON, and
send JSON to the server.
We can also convert any JSON received from the server into JavaScript
objects.
This way we can work with the data as JavaScript objects, with no
complicated parsing and translations.
But wait...
There is still ways to store your function, it's widely not recommended to that, but still possible:
We said, you can save a string... how about converting your function to a string then?
const data = {func: '()=>"a FUNC"'};
Then you can stringify data using JSON.stringify(data) and then using JSON.parse to parse it (if this step needed)...
And eval to execute a string function (before doing that, just let you know using eval widely not recommended):
eval(data.func)(); //return "a FUNC"
Via using NodeJS (commonJS syntax) I was able to get this type of functionality working, I originally had just a JSON structure inside some external JS file, but I wanted that structure to be more of a Class, with methods that could be decided at run time.
The declaration of 'Executor' in myJSON is not required.
var myJSON = {
"Hello": "World",
"Executor": ""
}
module.exports = {
init: () => { return { ...myJSON, "Executor": (first, last) => { return first + last } } }
}
Function expressions in the JSON are completely possible, just do not forget to wrap it in double quotes. Here is an example taken from noSQL database design:
{
"_id": "_design/testdb",
"views": {
"byName": {
"map": "function(doc){if(doc.name){emit(doc.name,doc.code)}}"
}
}
}
although eval is not recommended, this works:
<!DOCTYPE html>
<html>
<body>
<h2>Convert a string written in JSON format, into a JavaScript function.</h2>
<p id="demo"></p>
<script>
function test(val){return val + " it's OK;}
var someVar = "yup";
var myObj = { "func": "test(someVar);" };
document.getElementById("demo").innerHTML = eval(myObj.func);
</script>
</body>
</html>
Leave the quotes off...
var a = {"b":function(){alert('hello world');} };
a.b();