program story

경고 : "문자열 리터럴이 아니며 형식 인수가없는 형식"

inputbox 2020. 8. 2. 18:36
반응형

경고 : "문자열 리터럴이 아니며 형식 인수가없는 형식"


최신 Xcode 3.2.1 및 Snow Leopard로 업그레이드 한 후 경고 메시지가 표시됩니다

"문자열 리터럴이 아니며 형식 인수가없는 형식"

다음 코드에서 :

NSError *error = nil;

if (![self.managedObjectContext save:&error]) 
{
    NSLog([NSString stringWithFormat:@"%@ %@, %@", 
       errorMsgFormat, 
       error, 
       [error userInfo]]);      

}

경우 errorMsgFormat입니다 NSString형식 지정자와 (예 : "print me like this: %@"), 위의 문제 무엇을 NSLog호출? 경고가 생성되지 않도록 수정하는 권장 방법은 무엇입니까?


대괄호를 올바르게 중첩하고 있습니까? 나는 NSLog()하나의 주장 만 취하는 것을 좋아하지 않는다고 생각 합니다. 또한 이미 포맷되어 있습니다. 왜 이렇게하지?

NSLog(@"%@ %@, %@", 
   errorMsgFormat, 
   error, 
   [error userInfo]);              

또는 errorMsgFormat단일 자리 표시자가있는 형식 문자열 이라고 말하면 이 작업을 수행하려고합니까?

NSLog(@"%@, %@", [NSString stringWithFormat:errorMsgFormat, error], 
   [error userInfo]);              

보안 문제이기 때문에 Xcode가 불평하고 있습니다.

다음은 귀하와 유사한 코드입니다.

NSString *nameFormat = @"%@ %@";
NSString *firstName = @"Jon";
NSString *lastName = @"Hess %@";
NSString *name = [NSString stringWithFormat:nameFormat, firstName, lastName];
NSLog(name);

마지막 NSLog 문은 다음과 같은 기능을 수행합니다.

NSLog(@"Jon Hess %@");

NSLog가 하나 이상의 문자열 인수를 찾게 할 것이지만 하나는 없습니다. C 언어가 작동하는 방식 때문에 스택에서 임의의 가비지 포인터를 가져 와서 NSString처럼 취급하려고합니다. 이것은 아마도 프로그램을 중단시킬 것입니다. 이제 문자열에 % @가 없지만 언젠가는있을 수 있습니다. 형식 문자열 (printf, scanf, NSLog,-[NSString stringWithFormat :], ...)을 취하는 함수의 첫 번째 인수로 명시 적으로 제어하는 ​​데이터가있는 형식 문자열을 항상 사용해야합니다.

오토가 지적한 것처럼 아마도 다음과 같은 작업을 수행해야합니다.

NSLog(errorMsgFormat, error, [error userInfo]);

최종 답변 : Jon Hess가 말했듯이 형식 문자열을 기대하는 함수에 WHATEVER 문자열을 전달하기 때문에 보안 문제입니다. 즉, 모든 문자열 내에서 모든 형식 지정자를 평가합니다. 굉장한 것이 없다면, 나쁜 일이 발생할 수 있습니다.

따라서 올바른 작업은 형식 문자열을 직접 사용하는 것입니다 (예 :

NSLog(@"%@", myNSString);

그렇게하면 myNSString에 형식 지정자가 있어도 NSLog에 의해 평가되지 않습니다.


경고는 실제 경고이기 때문에 특히 사용하지 않는 것이 좋습니다. 언어를 동적으로 사용하면 런타임에 문자열로 작업을 수행 할 수 있습니다 (예 : 새로운 정보 삽입 또는 프로그램 충돌). 당신이 이것과 같아야한다는 것을 알고 있고 정말로 그것에 대해 경고하고 싶지 않다면 억압을 강요합니다.

#pragma GCC diagnostic ignored "-Wformat-security"

GCC에게 컴파일 경고를 일시적으로 무시하도록 지시 할 것입니다. 다시 해결하는 것은 아니지만 실제로 문제를 해결할 수있는 좋은 방법을 찾지 못할 수도 있습니다.

편집 : clang로 pragma가 변경되었습니다. 이 참조 https://stackoverflow.com/a/17322337/3937을


이를 해결하는 가장 빠른 방법 @"%@",NSLog호출 의 첫 번째 인수로 추가하는 것입니다 .

NSLog(@"%@", [NSString stringWithFormat: ....]);

그러나 Sixteen Otto의 대답을 고려해야합니다.


방금 경고를 무효화하기 위해 무효를 전달했습니다. 아마도 당신에게 도움이 될 것입니까?

NSLog (myString, nil);


If you want get rid of the warning "format not a string literal and no format arguments" once and for all, you can disable the GCC warning setting "Typecheck Calls to printf/scanf" (GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = NO) in your target's build settings.


NSLog() expects a format string, what is getting passed in is just a string. You do not need to use stringWithFormat:, you can just do:

NSLog(@"%@ %@, %@", errorMsgFormat, error, [error userInfo])

And that would make the warning go away.


FWIW, this applies to iPhone dev as well. I'm coding against the 3.1.3 SDK, and got the same error with the same problem (nesting stringWithFormat inside NSLog()). Sixten and Jon are on the money.


Just letting anyone know using the appendFormat on NSMutableString can also cause this warning to appear if trying to pass in a formatted string like so:

NSMutableString *csv = [NSMutableString stringWithString:@""];
NSString *csvAddition = [NSString stringWithFormat:@"%@",WHATEVERYOUAREPUTTINGINYOURSTRING];
[csv appendFormat:csvAddition];

So to avoid this warning, turn the above into this:

NSMutableString *csv = [NSMutableString stringWithString:@""];
[csv appendFormat:@"%@",WHATEVERYOUAREPUTTINGINYOURSTRING];

More concise and more secure. Enjoy!


NSLog(@"%@ %@, %@", 
       errorMsgFormat, 
       error, 
       [error userInfo]); 

참고URL : https://stackoverflow.com/questions/1677824/warning-format-not-a-string-literal-and-no-format-arguments

반응형