web-dev-qa-db-ger.com

Ziel C HTML Escape/Unescape

Ich frage mich, ob es einen einfachen Weg gibt, eine einfache HTML-Escape/Unescape-Umgebung in Ziel C zu erstellen. Was ich will, ist etwas wie dieser Pseudo-Code:

NSString *string = @"<span>Foo</span>";
[string stringByUnescapingHTML];

Welche zurückkehrt

<span>Foo</span>

Es ist zu hoffen, dass auch alle anderen HTML-Entities und auch ASCII -Codes wie Ӓ und dergleichen nicht mehr angezeigt werden.

Gibt es in Cocoa Touch/UIKit Methoden, um dies zu tun?

73
Alex Wayne

Dieser link enthält die Lösung unten. Cocoa CF verfügt über die Funktion CFXMLCreateStringByUnescapingEntities, die auf dem iPhone nicht verfügbar ist.

@interface MREntitiesConverter : NSObject <NSXMLParserDelegate>{
    NSMutableString* resultString;
}

@property (nonatomic, retain) NSMutableString* resultString;

- (NSString*)convertEntitiesInString:(NSString*)s;

@end


@implementation MREntitiesConverter

@synthesize resultString;

- (id)init
{
    if([super init]) {
        resultString = [[NSMutableString alloc] init];
    }
    return self;
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)s {
        [self.resultString appendString:s];
}

- (NSString*)convertEntitiesInString:(NSString*)s {
    if (!s) {
        NSLog(@"ERROR : Parameter string is nil");
    }
    NSString* xmlStr = [NSString stringWithFormat:@"<d>%@</d>", s];
    NSData *data = [xmlStr dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
    NSXMLParser* xmlParse = [[[NSXMLParser alloc] initWithData:data] autorelease];
    [xmlParse setDelegate:self];
    [xmlParse parse];
    return [NSString stringWithFormat:@"%@",resultString];
}

- (void)dealloc {
    [resultString release];
    [super dealloc];
}

@end
30
Andrew Grant

Schauen Sie sich meine NSString-Kategorie für XMLEntities an. Es gibt Methoden zum Entschlüsseln von XML-Entitäten (einschließlich aller HTML-Zeichenreferenzen), zum Verschlüsseln von XML-Entitäten, zum Entfernen von Tags und zum Entfernen von Zeilenumbrüchen und Leerzeichen aus einem String:

- (NSString *)stringByStrippingTags;
- (NSString *)stringByDecodingXMLEntities; // Including all HTML character references
- (NSString *)stringByEncodingXMLEntities;
- (NSString *)stringWithNewLinesAsBRs;
- (NSString *)stringByRemovingNewLinesAndWhitespace;
90

Eine weitere HTML-NSString-Kategorie aus Google Toolbox für Mac
Trotz des Namens funktioniert das auch auf iOS.

http://google-toolbox-for-mac.googlecode.com/svn/trunk/Foundation/GTMNSString+HTML.h

/// Get a string where internal characters that are escaped for HTML are unescaped 
//
///  For example, '&amp;' becomes '&'
///  Handles &#32; and &#x32; cases as well
///
//  Returns:
//    Autoreleased NSString
//
- (NSString *)gtm_stringByUnescapingFromHTML;

Ich musste nur drei Dateien in das Projekt aufnehmen: Header, Implementierung und GTMDefines.h.

35
Nikita Rybak

Dies ist eine unglaublich zusammen gehackte Lösung, die ich verwendet habe, aber wenn Sie einfach eine Zeichenfolge entkommen möchten, ohne sich Gedanken über das Parsen machen zu müssen, gehen Sie folgendermaßen vor:

-(NSString *)htmlEntityDecode:(NSString *)string
    {
        string = [string stringByReplacingOccurrencesOfString:@"&quot;" withString:@"\""];
        string = [string stringByReplacingOccurrencesOfString:@"&apos;" withString:@"'"];
        string = [string stringByReplacingOccurrencesOfString:@"&lt;" withString:@"<"];
        string = [string stringByReplacingOccurrencesOfString:@"&gt;" withString:@">"];
        string = [string stringByReplacingOccurrencesOfString:@"&amp;" withString:@"&"]; // Do this last so that, e.g. @"&amp;lt;" goes to @"&lt;" not @"<"

        return string;
    }

Ich weiß, dass es keineswegs elegant ist, aber es erledigt die Arbeit. Sie können ein Element dann decodieren, indem Sie Folgendes aufrufen:

string = [self htmlEntityDecode:string];

Wie gesagt, es ist hackig, aber es funktioniert. WENN Sie einen String kodieren möchten, kehren Sie einfach die Parameter stringByReplacingOccurencesOfString um.

28
Andrew Kozlik

In iOS 7 können Sie die Fähigkeit von NSAttributedString zum Importieren von HTML verwenden, um HTML-Entitäten in einen NSString zu konvertieren.

Z.B:

@interface NSAttributedString (HTML)
+ (instancetype)attributedStringWithHTMLString:(NSString *)htmlString;
@end

@implementation NSAttributedString (HTML)
+ (instancetype)attributedStringWithHTMLString:(NSString *)htmlString
{
    NSDictionary *options = @{ NSDocumentTypeDocumentAttribute : NSHTMLTextDocumentType,
                               NSCharacterEncodingDocumentAttribute :@(NSUTF8StringEncoding) };

    NSData *data = [htmlString dataUsingEncoding:NSUTF8StringEncoding];

    return [[NSAttributedString alloc] initWithData:data options:options documentAttributes:nil error:nil];
}

@end

Dann in Ihrem Code, wenn Sie die Entitäten bereinigen möchten:

NSString *cleanString = [[NSAttributedString attributedStringWithHTMLString:question.title] string];

Dies ist wahrscheinlich der einfachste Weg, aber ich weiß nicht, wie leistungsfähig es ist. Sie sollten wahrscheinlich ziemlich sicher sein, dass der Inhalt Ihrer "Bereinigung" keine <img>-Tags oder ähnliches enthält, da diese Methode diese Bilder während der HTML-Konvertierung in NSAttributedString herunterlädt. :)

11
orj

Hier ist eine Lösung, die alle Zeichen neutralisiert (indem sie alle HTML-codierten Entitäten für ihren Unicode-Wert erstellt) ... Verwendet dies für meine Bedürfnisse (um sicherzustellen, dass eine Zeichenfolge, die vom Benutzer stammt, aber in einem Webview platziert wurde, keine Zeichenfolge enthalten konnte) XSS-Angriffe):

Schnittstelle:

@interface NSString (escape)
- (NSString*)stringByEncodingHTMLEntities;
@end

Implementierung:

@implementation NSString (escape)

- (NSString*)stringByEncodingHTMLEntities {
    // Rather then mapping each individual entity and checking if it needs to be replaced, we simply replace every character with the hex entity

    NSMutableString *resultString = [NSMutableString string];
    for(int pos = 0; pos<[self length]; pos++)
        [resultString appendFormat:@"&#x%x;",[self characterAtIndex:pos]];
    return [NSString stringWithString:resultString];
}

@end

Verwendungsbeispiel:

UIWebView *webView = [[UIWebView alloc] init];
NSString *userInput = @"<script>alert('This is an XSS ATTACK!');</script>";
NSString *safeInput = [userInput stringByEncodingHTMLEntities];
[webView loadHTMLString:safeInput baseURL:nil];

Ihre Laufleistung wird variieren.

5
BadPirate

Die am wenigsten invasive und leichteste Methode zum Kodieren und Dekodieren von HTML- oder XML-Zeichenfolgen ist die Verwendung von GTMNSStringHTMLAdditions CocoaPod .

Es handelt sich lediglich um die Google Toolbox für Mac NSString-Kategorie GTMNSString+HTML, ohne die Abhängigkeit von GTMDefines.h. Alles, was Sie hinzufügen müssen, ist eine .h und eine .m, und Sie können loslegen.

Beispiel:

#import "GTMNSString+HTML.h"

// Encoding a string with XML / HTML elements
NSString *stringToEncode = @"<TheBeat>Goes On</TheBeat>";
NSString *encodedString = [stringToEncode gtm_stringByEscapingForHTML];

// encodedString looks like this now:
// &lt;TheBeat&gt;Goes On&lt;/TheBeat&gt;

// Decoding a string with XML / HTML encoded elements
NSString *stringToDecode = @"&lt;TheBeat&gt;Goes On&lt;/TheBeat&gt;";
NSString *decodedString = [stringToDecode gtm_stringByUnescapingFromHTML];

// decodedString looks like this now:
// <TheBeat>Goes On</TheBeat>
4
T Blank

Dies ist eine einfach zu verwendende Implementierung der NSString-Kategorie:

Es ist bei weitem nicht vollständig, aber Sie können hier einige fehlende Elemente hinzufügen: http://code.google.com/p/statz/source/browse/trunk/NSString%2BHTML.m

Verwendungszweck:

#import "NSString+HTML.h"

NSString *raw = [NSString stringWithFormat:@"<div></div>"];
NSString *escaped = [raw htmlEscapedString];
2
Blago

Der MREntitiesConverter oben ist ein HTML-Stripper und kein Encoder.

Wenn Sie einen Encoder benötigen, gehen Sie hier: Encode NSString für XML/HTML

1
Brain2000

MREntitiesConverter funktioniert nicht, um fehlerhafte XML-Dateien zu umgehen. Es wird bei einer einfachen URL fehlschlagen:

http://www.google.com/search?client=safari&rls=de&q=fail&ie=UTF-8&oe=UTF-8

0
richcollins

Wenn Sie ein Literal generieren müssen, können Sie ein Werkzeug wie das folgende verwenden:

http://www.freeformatter.com/Java-dotnet-escape.html#ad-output

um die Arbeit für Sie zu erledigen.

Siehe auch diese Antwort .

0
diadyne

Diese einfachste Lösung ist das Erstellen einer Kategorie wie folgt:

Hier ist die Header-Datei der Kategorie:

#import <Foundation/Foundation.h>
@interface NSString (URLEncoding)
-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding;
@end

Und hier ist die Implementierung:

#import "NSString+URLEncoding.h"
@implementation NSString (URLEncoding)
-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding {
    return (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,
               (CFStringRef)self,
               NULL,
               (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ",
               CFStringConvertNSStringEncodingToEncoding(encoding));
}
@end

Und jetzt können wir das einfach tun:

NSString *raw = @"hell & brimstone + earthly/delight";
NSString *url = [NSString stringWithFormat:@"http://example.com/example?param=%@",
            [raw urlEncodeUsingEncoding:NSUTF8Encoding]];
NSLog(url);

Die Credits für diese Antwort gehen auf die folgende Website: -

http://madebymany.com/blog/url-encoding-an-nsstring-on-ios
0
Hashim Akhtar