How do i convert an NSString to a NSDictionary Object? Or
initialize an NSDictionary from an NSString?
Here is an NSString to be converted. Inside this dictionary example, there is an array inserted:
{
("My value.")
}
You probably want to use JSON strings that can be easily converted (via NSData) from and to NSArrays and NSDictionarys.
See NSJSONSerialization:
http://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSJSONSerialization_Class/Reference/Reference.html
I think your object should be in key value format like this...
{
"myData":("My value.")
}
Related
Using Json.NET
JsonConvert.SerializeObject(new { Property = "<script>alert('o hai');</script>" })
returns
{"Property":"<script>alert('o hai');</script>"}
Is it possible for the value to be escaped by SerializeObject to prevent a hostile script from executing? I'd prefer not to make changes to the object itself.
Edit: Ideally I'd like to integrate the sanitizing into the SerializeObject call without having to process the object before or after SerializeObject.
Edit: The string output from JsonConvert.SerializeObject is assigned to a global variable in a script block, which I believe is where the XSS issue is.
Functionality to achieve this was added in version 4.5.11
This allows you to add various type of escaping to the output.
This is my LinqPad test:
var settings = new JsonSerializerSettings();
settings.StringEscapeHandling = StringEscapeHandling.EscapeHtml;
var output = JsonConvert.SerializeObject(new { Property = "<script>alert('o hai');</script>" }, settings);
Debug.Print(output);
outputs
{"Property":"\u003cscript\u003ealert(\u0027o hai\u0027);\u003c/script\u003e"}
Just as a disclaimer, this isn't a golden bullet to fix xss, but should help you mitigate it a bit given your example.
This may not be ideal but this is my solution (for now, at least):
JsonConvert.SerializeObject(new { Property = "<script>alert('o hai');</script>" }, new HtmlEncodeStringPropertiesConverter());
with a simple JsonConverter that performs HtmlEncode on the value if it is a string
public class HtmlEncodeStringPropertiesConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(string);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteValue(Encoder.HtmlEncode(value.ToString()));
}
}
(Encoder is Microsoft.Security.Application.Encoder from the AntiXSS library)
In .NET Core 3.0, System.Text.Json.JsonSerializer escapes html characters by default.
var text = "<script>alert('o hai');</script>";
var json = System.Text.Json.JsonSerializer.Serialize(new { Property = text });
Console.WriteLine(json);
Output
// .NETCoreApp,Version=v3.0
{"Property":"\u003Cscript\u003Ealert(\u0027o hai\u0027);\u003C/script\u003E"}
Documentation
How to serialize and deserialize JSON in .NET in Serialization behavior section says:
The default encoder escapes non-ASCII characters, HTML-sensitive characters within the ASCII-range, and characters that must be escaped according to the JSON spec.
Please also check the remarks for JavaScriptEncoder.UnsafeRelaxedJsonEscaping because it contains a series of remarks starting with Unlike the Default.
I don't want to escape it
JavaScriptEncoder.UnsafeRelaxedJsonEscaping needs to be set to turn off the default behavior.
var options = new System.Text.Json.JsonSerializerOptions() {
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
};
var json2 = System.Text.Json.JsonSerializer.Serialize(new { Property = text }, options);
Console.WriteLine(json2);
{"Property":"<script>alert('o hai');</script>"}
UnsafeRelaxedJsonEscaping's Documentation
Remarks for UnsafeRelaxedJsonEscaping:
Unlike the Default encoder, this encoder instance does not escape HTML-sensitive characters such as <, >, &. As a result, it must be used cautiously; for example, it can be used if the output data is within a response whose content-type is known with a charset set to UTF-8.
Unlike the Default encoding, the quotation mark is encoded as " rather than \u0022.
Unlike the Default encoding (which only allows UnicodeRanges.BasicLatin), using this encoder instance allows UnicodeRanges.All to go through unescaped.
Unlike the Default encoder, this encoder instance allows some other characters (such as '+') to go through unescaped and therefore must be used cautiously.
No, JSON.NET is a JSON serializer. It is not a XSS sanitizer. You may take a look at the AntiXSS library from Microsoft. Here's an article on MSDN about its usage (a little outdated but still relevant).
I have a serializable class that I would like to provide my own toString when being serialized to JSON.
DEFINE PUBLIC PROPERTY address1 AS CHARACTER NO-UNDO
GET.
SET.
METHOD PUBLIC OVERRIDE CHARACTER toString( ):
DEFINE VARIABLE result AS CHARACTER NO-UNDO.
RETURN address1 + address2 + city + country.
END METHOD.
END CLASS. ```
I am also assigning the class to a temptable and using the write-json method of a dataset to output but I get the standard toString representation .."myClass": {
"prods:objId": 1,
"myClass": {
"address1": "xxxxx"
}
}
can I somehow override the toString being used ?
The JsonSerializer does not use ToString() ,nor does it give you any control over the format that's produced. The Serialize method describes what data is written. If you want this ability added into the ABL, you can add an "Idea" at https://openedge.ideas.aha.io/ideas ; OE product management review these ideas periodically.
If you want control today over what is written, you will need to roll your own. By way of example, OE has the IJsonSerializer interface, which allows types to declare that they can be serialised using the JsonSerializer class.
There's a property Path on JToken.
But it escapes the name of object with "[' ']" if the object name contains a "."
XPATH : dir/nested_dir/file.txt
JSON: dir.nested_dir.['file.txt']
Is there some other property that will return the path as an array of string ?
As pointed out here: https://stackoverflow.com/a/19727164/1555435
Use brackets and quotes around your field. For example, if your field is valid.key.with.dot
Refer to it as ['valid.key.with.dot'] and in JsonPath, try
JsonPath.read(jsonString, "$.['valid.key.with.dot']")
Check out this dotNetFiddle
There is not a built-in property that does this, but you can make an extension method that does what you want easily enough:
public static class JsonExtensions
{
public static string[] PathAsArray (this JToken token)
{
return token.AncestorsAndSelf()
.OfType<JProperty>()
.Select(p => p.Name)
.Reverse()
.ToArray();
}
}
Then use it like this:
var pathArray = token.PathAsArray();
Console.WriteLine(string.Join("/", pathArray));
Fiddle: https://dotnetfiddle.net/GOdo7t
Note: the above extension method ignores any JArrays that might be in the path. You will need to make adjustments to the code if you need to handle arrays.
I'm working in Objective-C to Swift mixed project and am seeing the following error message when trying to retrieve an object that I know to be a string: "AnyObject" is not identical to "String".
I really don't want to explicitly specify every single time what I'm getting out of a collection. How can I supress compiler errors like this and let me work with anyobject like Objective-C id types?
let dict = (dataSource.array[indexPath.row]) as NSDictionary
cell.titleLabel.text = dict.objectForKey("done")! as String
EDIT:
Safer solution is to check if you can cast object from dictionary to string
if let dict = dataSource.array[indexPath.row] as? NSDictionary {
cell.titleLabel.text = (dict.objectForKey("done") as? String) ?? ""
}
Using WSDL2ObjC I am getting lot of classes which are subclasses of NSString.
I am finding it troublesome to initialize the NSString value of any object of those classes.
Say my class looks like this :
#interface mClass ; NSString {
int value;
}
Now in my code I would like to use objects of mClass as both NSString and also want to use its attribute value which is an integer.
How can I do that?
I am trying to use code like this
mClass *obj = [[mClass alloc] initWithString:#"Hello"];
But it's showing me an error saying I am using an abstract object of a class , I should use concrete instance instead.
If you really need make NSString subclass you should override 3 methods:
- (instancetype)initWithCharactersNoCopy:(unichar *)characters length:(NSUInteger)length freeWhenDone:(BOOL)freeBuffer;
- (NSUInteger)length;
- (unichar)characterAtIndex:(NSUInteger)index;
For example:
MyString.h
#interface MyString : NSString
#property (nonatomic, strong) id myProperty;
#end
MyString.m
#interface MyString ()
#property (nonatomic, strong) NSString *stringHolder;
#end
#implemenation MyString
- (instancetype)initWithCharactersNoCopy:(unichar *)characters length:(NSUInteger)length freeWhenDone:(BOOL)freeBuffer {
self = [super init];
if (self) {
self.stringHolder = [[NSString alloc] initWithCharactersNoCopy:characters length:length freeWhenDone:freeBuffer];
}
return self;
}
- (NSUInteger)length {
return self.stringHolder.length;
}
- (unichar)characterAtIndex:(NSUInteger)index {
return [self.stringHolder characterAtIndex:index];
}
#end
It might be smarter to use a wrapper class that internally uses NSStrings to do whatever operations or manipulations you are trying to do. However this will cause you to need to overload any functionality of NSString you want (such as getting the length of the string).
Or, you could create a category of NSString (found right next to Objective-C class in the new file window). This allows you to add any properties or methods that you wish to be "added" to the NSString class. Now just import this category wherever you wish to use it and you will have all of your custom functions available on any NSStrings objects.
Do you really need to subclass NSString? It’s a class cluster, which (apart from other things) means it’s hard to subclass. There’s a good post by Mike Ash on subclassing class clusters. If you didn’t know that class clusters existed you are probably new to Cocoa and in that case the best short answer is don’t try to subclass class clusters.
There’s also previous questions about subclassing NSString here on Stack Overflow. Next time you might want to search a bit before asking a new question.