Seit dem Upgrade auf den neuesten Xcode 3.2.1 und Snow Leopard habe ich die Warnung erhalten
"Format kein String-Literal und keine Formatargumente"
aus dem folgenden Code:
NSError *error = nil;
if (![self.managedObjectContext save:&error])
{
NSLog([NSString stringWithFormat:@"%@ %@, %@",
errorMsgFormat,
error,
[error userInfo]]);
}
Wenn errorMsgFormat
es sich um ein NSString
Formatformat handelt (z. B. :) "print me like this: %@"
, was ist mit dem obigen NSLog
Aufruf falsch ? Und wie kann das Problem behoben werden, damit die Warnung nicht generiert wird?
quelle
NSLog()
kann ein Argument annehmen, wenn die Formatzeichenfolge keine Formatspezifizierer enthält.Xcode beschwert sich, weil dies ein Sicherheitsproblem ist.
Hier ist ein ähnlicher Code wie Sie:
Diese letzte NSLog-Anweisung wird das Äquivalent dazu ausführen:
Das wird dazu führen, dass NSLog nach einem weiteren String-Argument sucht, aber es gibt keines. Aufgrund der Funktionsweise der C-Sprache wird ein zufälliger Müllzeiger vom Stapel aufgenommen und versucht, ihn wie einen NSString zu behandeln. Dies wird höchstwahrscheinlich Ihr Programm zum Absturz bringen. Jetzt enthalten Ihre Zeichenfolgen wahrscheinlich keine% @, aber eines Tages könnten sie. Sie sollten immer eine Formatzeichenfolge mit Daten verwenden, die Sie explizit als erstes Argument für Funktionen steuern, die Formatzeichenfolgen annehmen (printf, scanf, NSLog, - [NSString stringWithFormat:], ...).
Wie Otto betont, sollten Sie wahrscheinlich nur Folgendes tun:
quelle
Endgültige Antwort: Wie Jon Hess sagte, handelt es sich um ein Sicherheitsproblem, da Sie eine WHATEVER-Zeichenfolge an eine Funktion übergeben, die eine Formatzeichenfolge erwartet. Das heißt, es werden alle Formatbezeichner INNERHALB der beliebigen Zeichenfolge ausgewertet. Wenn es keine gibt, großartig, aber wenn es welche gibt, könnten schlimme Dinge passieren.
Das Richtige ist also, beispielsweise eine Formatzeichenfolge direkt zu verwenden
Auf diese Weise werden Formatspezifizierer, selbst wenn sie in myNSString vorhanden sind, nicht von NSLog ausgewertet.
quelle
Ich empfehle dies nicht besonders, da die Warnung eine echte Warnung ist. Bei einer dynamischen Verwendung der Sprache ist es möglich, Dinge zur Laufzeit mit der Zeichenfolge zu tun (dh neue Informationen einzufügen oder sogar das Programm zum Absturz zu bringen). Dies ist jedoch möglich zu unterdrücken erzwingen, wenn Sie wissen, dass es so sein sollte und Sie wirklich nicht davor gewarnt werden wollen ..
#pragma GCC diagnostic ignored "-Wformat-security"
Würde GCC anweisen, die Kompilierungswarnung vorübergehend zu ignorieren. Wiederum löst es nichts, aber es kann vorkommen, dass Sie keinen guten Weg finden, um das Problem tatsächlich zu beheben.
EDIT: Seit dem Klirren hat sich das Pragma geändert. Siehe hierzu: https://stackoverflow.com/a/17322337/3937
quelle
Der schnellste Weg, dies zu beheben, besteht darin
@"%@",
, IhremNSLog
Anruf als erstes Argument hinzuzufügen , d. H.Allerdings sollten Sie wahrscheinlich die Antwort von Sechzehn Otto in Betracht ziehen.
quelle
Ich habe gerade eine Null übergeben, um die Warnungen zu negieren. Vielleicht würde das für Sie funktionieren?
NSLog (myString, nil);
quelle
myString
, ist der erste in Ordnung, aber der zweite nimmt Müll vom Stapel auf. Die Substitutionsliste inNSLog()
wird niemals beendetnil
, @Sold. Es gibt zwei Möglichkeiten, um herauszufinden, wie lang die Liste der Argumente ist: ein Sentinel-Wert oder was inprintf()
und in der Familie verwendet wird - ein weiteres Argument, das die Berechnung der Anzahl ermöglicht (z. B. durch Zählen der Formatspezifizierer).Wenn Sie die Warnung "Format kein Zeichenfolgenliteral und keine Formatargumente" ein für alle Mal entfernen möchten, können Sie die GCC-Warneinstellung "Typecheck Calls to printf / scanf" (GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = NO) in den Build-Einstellungen Ihres Ziels deaktivieren.
quelle
NSLog () erwartet eine Formatzeichenfolge. Was übergeben wird, ist nur eine Zeichenfolge. Sie müssen stringWithFormat: nicht verwenden. Sie können einfach Folgendes tun:
NSLog(@"%@ %@, %@", errorMsgFormat, error, [error userInfo])
Und das würde die Warnung verschwinden lassen.
quelle
FWIW, dies gilt auch für iPhone-Entwickler. Ich codiere gegen das 3.1.3 SDK und habe denselben Fehler mit demselben Problem erhalten (Verschachtelung von stringWithFormat in NSLog ()). Sixten und Jon sind auf dem Geld.
quelle
appendFormat
Wenn Sie nur jemanden über die Verwendung von on NSMutableString informieren, kann diese Warnung auch angezeigt werden, wenn Sie versuchen, eine formatierte Zeichenfolge wie folgt zu übergeben:Um diese Warnung zu vermeiden, gehen Sie wie folgt vor:
Prägnanter und sicherer. Genießen!
quelle
quelle
stringWithFormat
ist hier überflüssig, wenn Sie nur tun könntenNSLog(@"%@ %@, %@", errorMsgFormat, error, [error userInfo])