I'm developing an application for the iPhone that has inApp-mail sending capabilities. So far so good, but now I want to avoid html-injections as some parts of the mail are user-generated texts.
Basically I search for something like this:
// inits
NSString *sourceString = [NSString stringWithString:#"Hello world! Grüße dich Welt <-- This is in German."];
// ----- THAT'S WHAT I'M LOOKING FOR
// pseudo-code |
// V
NSString *htmlEncodedString = [sourceString htmlEncode];
// log
NSLog(#"source string: %#", sourceString);
NSLog(#"encoded string: %#", htmlEncodedString);
Expected output
source string: Hello world! Grüße dich Welt <-- This is in German.
encoded string: Hello world! Grüße dich Welt <-- This is in German.
I already googled and looked through several of SO's questions and answers, but all of them seem to be related to URL-encoding and that's not what I really need (I tried stringByAddingPercentEscapesUsingEncoding with no luck - it creates %C3%BC out of an 'ü' that should be an ü).
A code sample would be really great (correcting mine?)...
--
Thanks in advance,
Markus
Check out my NSString category for HTML. Here are the methods available:
- (NSString *)stringByConvertingHTMLToPlainText;
- (NSString *)stringByDecodingHTMLEntities;
- (NSString *)stringByEncodingHTMLEntities;
- (NSString *)stringWithNewLinesAsBRs;
- (NSString *)stringByRemovingNewLinesAndWhitespace;
Thanks #all. I ended up using my own implementation:
//
// _________________________________________
//
// textToHtml
// _________________________________________
//
- (NSString*)textToHtml:(NSString*)htmlString {
htmlString = [htmlString stringByReplacingOccurrencesOfString:#"&" withString:#"&"];
htmlString = [htmlString stringByReplacingOccurrencesOfString:#"<" withString:#"<"];
htmlString = [htmlString stringByReplacingOccurrencesOfString:#">" withString:#">"];
htmlString = [htmlString stringByReplacingOccurrencesOfString:#"""" withString:#"""];
htmlString = [htmlString stringByReplacingOccurrencesOfString:#"'" withString:#"'"];
htmlString = [htmlString stringByReplacingOccurrencesOfString:#"\n" withString:#"<br>"];
return htmlString;
}
A little improvement on #Markus' code [Change <br /> to <p></p>, escape multiple spaces]
- (NSString*)textToHtml:(NSString*)htmlString {
htmlString = [htmlString stringByReplacingOccurrencesOfString:#"&" withString:#"&"];
htmlString = [htmlString stringByReplacingOccurrencesOfString:#"<" withString:#"<"];
htmlString = [htmlString stringByReplacingOccurrencesOfString:#">" withString:#">"];
htmlString = [htmlString stringByReplacingOccurrencesOfString:#"""" withString:#"""];
htmlString = [htmlString stringByReplacingOccurrencesOfString:#"'" withString:#"'"];
htmlString = [#"<p>" stringByAppendingString:htmlString];
htmlString = [htmlString stringByAppendingString:#"</p>"];
htmlString = [htmlString stringByReplacingOccurrencesOfString:#"\n" withString:#"</p><p>"];
// htmlString = [htmlString stringByReplacingOccurrencesOfString:#"\n" withString:#"<br />"];
while ([htmlString rangeOfString:#" "].length > 0) {
htmlString = [htmlString stringByReplacingOccurrencesOfString:#" " withString:#" "];
}
return htmlString;
}
I have been looking for a similar solution and this did the job for me
NSString* value = #"<&>";
const void* keys[1] = {CFSTR("somekey")};
const void* values[1] = {value};
CFDictionaryRef dicRef = CFDictionaryCreate(kCFAllocatorDefault, keys, values, 1, nil, nil);
CFDataRef dataRef = CFPropertyListCreateData(kCFAllocatorDefault, dicRef, kCFPropertyListXMLFormat_v1_0, 0, NULL);
NSString *str = [[NSString alloc]initWithData:(NSData *)dataRef encoding:NSUTF8StringEncoding];
NSRange start =[str rangeOfString:#"string>"];
NSRange end =[str rangeOfString:#"</string"];
NSString *substr = [str substringWithRange:NSMakeRange(start.location+start.length, end.location-(start.location+start.length))];
[str release];
CFRelease(dicRef);
CFRelease(dataRef);
//Substring is now html entity encoded
I am using some of the features that is used when saving plist files. I hope this helps.
I'm expanding #Markus answer, because my case is i'm sending JSON string, so i need to added some escape, these are my function :
note :
the exception reference from w3schools. https://www.w3schools.com/tags/ref_urlencode.asp
- (NSString*)convertStringToHTMLEscape:(NSString*)stringContent
{
stringContent = [stringContent stringByReplacingOccurrencesOfString:#"{" withString:#"%7B"];
stringContent = [stringContent stringByReplacingOccurrencesOfString:#"}" withString:#"%7D"];
stringContent = [stringContent stringByReplacingOccurrencesOfString:#"[" withString:#"%5B"];
stringContent = [stringContent stringByReplacingOccurrencesOfString:#"]" withString:#"%5D"];
stringContent = [stringContent stringByReplacingOccurrencesOfString:#" " withString:#"%20"];
stringContent = [stringContent stringByReplacingOccurrencesOfString:#"\"" withString:#"%22"];
stringContent = [stringContent stringByReplacingOccurrencesOfString:#"\\" withString:#"%5C"];
stringContent = [stringContent stringByReplacingOccurrencesOfString:#"/" withString:#"%2F"];
return stringContent;
}
Assuming the character encoding of the email supports Unicode - say UTF-8 - could you not just find and replace the occurrences of <, >, and & with <, >, and &?
Related
How do I parse HTML file?
I'm getting an HTML file in the below code,I just want to get data in between BinarySecurityToken XML node.
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
if(_data)
{
//Here am getting the below HTML content
NSString* content = [[NSString alloc] initWithData:_data
encoding:NSUTF8StringEncoding];
}
}
<input type="hidden" name="wa" value="wsignin1.0" />
<input type="hidden" name="wresult"
value="<t:RequestSecurityTokenResponse xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust">
<t:Lifetime>
<wsu:Created >2013-04-29T11:50:29.895Z</wsu:Created>
<wsu:Expires>2013-04-29T12:00:29.895Z</wsu:Expires>
</t:Lifetime>
<wsp:AppliesTo>
<EndpointReference>
<Address>urn:orin.converse</Address>
</EndpointReference></wsp:AppliesTo>
<t:RequestedSecurityToken>
<wsse:BinarySecurityToken>
aHR0cCUzYSUyZiUyZnNjaGVtYWd0Sjk0JTNk
</wsse:BinarySecurityToken>
Any ideas? Thanks in advance.
You can get using this code
NSRange divRange = [content rangeOfString:#"<wsse:BinarySecurityToken>" options:NSCaseInsensitiveSearch];
if (divRange.location != NSNotFound)
{
NSRange endDivRange;
endDivRange.location = divRange.length + divRange.location;
endDivRange.length = [content length] - endDivRange.location;
endDivRange = [content rangeOfString:#"</wsse:BinarySecurityToken>" options:NSCaseInsensitiveSearch range:endDivRange];
if (endDivRange.location != NSNotFound)
{
divRange.location += divRange.length;
divRange.length = endDivRange.location - divRange.location;
NSLog(#"BinarySecurityToken : %#",[content substringWithRange:divRange]);
}
}
Output :
aHR0cCUzYSUyZiUyZnNjaGVtYWd0Sjk0JTNk
You need and XML parser for that.
There's a tutorial here
For this particular case you can get the ranges of <wsse:BinarySecurityToken> and </wsse:BinarySecurityToken>, construct new range that will provide you location of the token, and get substring in that range.
Sample code:
NSRange openingTagRange = [htmlString rangeOfString:#"<wsse:BinarySecurityToken>"];
NSRange closingTagRange = [htmlString rangeOfString:#"</wsse:BinarySecurityToken>"];
NSRange tokenRange = NSMakeRange(openingTagRange.location + openingTagRange.length, closingTagRange.location - (openingTagRange.location + openingTagRange.length));
NSString *token = [htmlString substringWithRange:tokenRange];
Since your input comes from outside, you should probably check if the ranges' locations are not equal to NSNotFound.
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"index" ofType:#"html"];
NSData * data = [NSData dataWithContentsOfFile:filePath];
TFHpple * tutorialsParser = [[TFHpple alloc] initWithHTMLData:data];
NSString *query = #"//div[#id='BinarySecurityToken']";
NSArray *nodes = [tutorialsParser searchWithXPathQuery:query];
for (TFHppleElement * element in nodes) {
NSLog(#"%#", element);
NSLog(#"%#", [element tagName]);
NSLog(#"%#", [element attributes]);
NSLog(#"%#", [element children]);
for (TFHppleElement *childElement in [element children]) {
NSLog(#"%#", childElement);
}
}
hope this will help you For more try this blog and Git Project Resource may help you and
Good blog by RAYWENDERLICH
or another option if you have all the HTML data in NSString you can get data between specific NSString with this function.
-(NSString*)stringBetweenString:(NSString*)start andString:(NSString)end {
NSRange startRange = [self rangeOfString:start];
if (startRange.location != NSNotFound) {
NSRange targetRange;
targetRange.location = startRange.location + startRange.length;
targetRange.length = [self length] - targetRange.location;
NSRange endRange = [self rangeOfString:end options:0 range:targetRange];
if (endRange.location != NSNotFound) {
targetRange.length = endRange.location - targetRange.location;
return [self substringWithRange:targetRange];
}
}
return nil;
}
I'm creating one chatting application.but,now I'm facing one problem while sending special character "&". I'm Using php web-services for sending and receiving the messages.while sending "&" character,and after that when some one received this character,the application is crashed.
here replace that character with its code like bellow...
when pass it in web-service at that time replace it like bellow..
yourString = [yourString stringByReplacingOccurrencesOfString:#"&" withString:#"&"];
and then when you want to receive it at that time replace with special character..
yourString = [yourString stringByReplacingOccurrencesOfString:#"&" withString:#"&"];
after display it in UITextView or UITextField
UPDATE:
if (string2 != nil) {
string1 = [NSString stringWithString:string2];
NSString *strTemp = [NSString stringWithString:string2];
NSLog(#"\n\n Temp String ==>> %#",strTemp);
}
UPDATE:
NSString *yourString = #"Hello & How Are You?";
yourString = [yourString stringByReplacingOccurrencesOfString:#"&" withString:#"&"];
NSLog(#"\n\n String Here => %#",yourString);
At sending string to web-serive use bellow strign..
NSString *yourStringForWeb = #"Hello & How Are You?";
yourStringForWeb = [yourStringForWeb stringByReplacingOccurrencesOfString:#"&" withString:#"&"];
and pass this yourStringForWeb to the web-service...
NSString *string = #"Hello & How Are You?";
string = [string stringByReplacingOccurrencesOfString:#"&" withString:#"&"];
string = [string stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
string = [string stringByReplacingOccurrencesOfString:#"&" withString:#"%26"];
NSLog(#"\n\n ===>> Before ==>> %#",string);
NSString *string2 = string;
string2 = [string2 stringByReplacingOccurrencesOfString:#"%20" withString:#" "];
string2 = [string2 stringByReplacingOccurrencesOfString:#"%26" withString:#"&"];
NSLog(#"\n\n ===>> After ==>> %#",string2);
OutPut =>
===>> Before ==>> Hello%20%26%20How%20Are%20You?
===>> After ==>> Hello & How Are You?
I‘m using TouchXML for parsing WSDL file, and i'm a new to it, There's a NSString like this
NSString *str = #"<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><soap:Body><ns1:createSessionResponse xmlns:ns1=\"http://soap.user/\"><ns1:out>9E0B34E6DFF7BF89</ns1:out></ns1:createSessionResponse></soap:Body></soap:Envelope>";
How can I get the string 9E0B34E6DFF7BF89 in "ns:out"
Try this :
NSString *str = #"<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><soap:Body><ns1:createSessionResponse xmlns:ns1=\"http://soap.user/\"><ns1:out>9E0B34E6DFF7BF89</ns1:out></ns1:createSessionResponse></soap:Body></soap:Envelope>";
NSRange rr2 = [str rangeOfString:#"<ns1:out>"];
NSRange rr3 = [str rangeOfString:#"</ns1:out>"];
int lengt = rr3.location - rr2.location - rr2.length;
int location = rr2.location + rr2.length;
NSRange aa;
aa.location = location;
aa.length = lengt;
str = [str substringWithRange:aa];
NSLog(#"%#",str); // 9E0B34E6DFF7BF89
I have used this code for replacing "\n" with "", but it is not working.
How can I do it?
NSString *descString = [values objectForKey:#"description"];
descString = [descString stringByReplacingOccurrencesOfString:#"\n" withString:#""];
NSLog(#"Description String ---->>> %#",descString);
catlog.description = descString;
[webview loadHTMLString:catlog.description baseURL:nil];
webview.opaque = NO;
try this
NSString *s = #"foo/bar:baz.foo";
NSCharacterSet *doNotWant = [NSCharacterSet characterSetWithCharactersInString:#"/:."];
s = [[s componentsSeparatedByCharactersInSet: doNotWant] componentsJoinedByString: #""];
NSLog(#"%#", s);
descString = [descString stringByReplacingOccurrencesOfString:#"\\n" withString:#""];
For more information refer to stringByReplacingOccurrencesOfString:withString: method
Hope this helps you.
UPDATE
Swift 3.0
descString.replacingOccurrences(of: "\\n", with: "");
and If I am not wring it will also work for Swift 4.0
I have an NSString *str, having value #"I like Programming and gaming."
I have to remove "I" "like" & "and" from my string so it should look like as "Programming gaming"
How can I do this, any Idea?
NSString *newString = #"I like Programming and gaming.";
NSString *newString1 = [newString stringByReplacingOccurrencesOfString:#"I" withString:#""];
NSString *newString12 = [newString1 stringByReplacingOccurrencesOfString:#"like" withString:#""];
NSString *final = [newString12 stringByReplacingOccurrencesOfString:#"and" withString:#""];
Assigned to wrong string variable edited now it is fine
NSLog(#"%#",final);
output : Programming gaming
NSString * newString = [#"I like Programming and gaming." stringByReplacingOccurrencesOfString:#"I" withString:#""];
newString = [newString stringByReplacingOccurrencesOfString:#"like" withString:#""];
newString = [newString stringByReplacingOccurrencesOfString:#"and" withString:#""];
NSLog(#"%#", newString);
More efficient and maintainable than doing a bunch of stringByReplacing... calls in series:
NSSet* badWords = [NSSet setWithObjects:#"I", #"like", #"and", nil];
NSString* str = #"I like Programming and gaming.";
NSString* result = nil;
NSArray* parts = [str componentsSeparatedByString:#" "];
for (NSString* part in parts) {
if (! [badWords containsObject: part]) {
if (! result) {
//initialize result
result = part;
}
else {
//append to the result
result = [NSString stringWithFormat:#"%# %#", result, part];
}
}
}
It is an old question, but I'd like to show my solution:
NSArray* badWords = #[#"the", #"in", #"and", #"&",#"by"];
NSMutableString* mString = [NSMutableString stringWithString:str];
for (NSString* string in badWords) {
mString = [[mString stringByReplacingOccurrencesOfString:string withString:#""] mutableCopy];
}
return [NSString stringWithString:mString];
Make a mutable copy of your string (or initialize it as NSMutableString) and then use replaceOccurrencesOfString:withString:options:range: to replace a given string with #"" (empty string).