PVS-Studio 7.34 릴리스에서는 Java용 오염 분석, C#용 Unity 관련 진단 규칙, OWASP 심층 분석 등 다양한 새로운 진단 규칙이 분석기에 도입되었습니다. 이 기사에서는 모든 내용을 다룰 것입니다.
이번 릴리스에서 C 팀은 일반 분석 진단 규칙과 다양한 소프트웨어 개발 표준 지원에 중점을 두었습니다.
하지만 모자를 꽉 쥐세요. 이것은 시작에 불과합니다! 팀은 더 많은 MISRA 표준 진단 규칙을 다룰 계획이므로 더 많은 소식을 기대해주세요 :)
지금은 7.34 릴리스의 주요 규칙을 살펴보겠습니다.
이 진단 규칙은 설명 메시지 없이 생성된 예외를 감지하도록 설계되었습니다.
메시지가 없으면 오류 감지 및 수정 과정은 물론 전반적인 코드 가독성이 저하될 수 있습니다.
다음은 PVS-Studio 분석기가 경고를 생성하도록 만드는 코드의 예입니다.
void SomeCheck(const char *val) { if (!val) throw std::runtime_error { "" }; .... } void Foo() { const char *val = ....; try { SomeCheck(val); // <= } catch(std::runtime_error &err) { std::cerr << err.what() << std::endl; } }
오류가 발생하면 SomeCheck 함수는 빈 메시지와 함께 예외를 발생시키며 이는 Foo 함수에서 처리됩니다. 처리 중에 std::cerr에는 예외 이유에 대한 정보가 포함될 것으로 예상되지만 그렇지 않습니다.
이렇게 코드를 작성함으로써 개발자는 동료들에게 "행복한 디버깅"을 기원하는 마음을 전합니다. 이는 실패의 정확한 원인을 이해하는 데 방해가 됩니다.
이 규칙은 표준 예외에 적용됩니다. 사용자 정의 주석 메커니즘을 사용하여 사용자 정의 예외에 대한 경고를 발행할 수 있습니다.
이 진단 규칙에 대한 자세한 내용은 설명서를 확인하세요.
이 진단 규칙은 C 언어에만 적용됩니다.
const 또는 휘발성 한정자를 사용하는 함수 유형 정의의 경우를 감지하는 것을 목표로 합니다.
C23 표준(문단 6.7.4.1의 10번째 항목)에 따르면 이러한 유형을 사용하면 정의되지 않은 동작이 발생합니다.
PVS-Studio 분석기가 경고를 생성하는 코드 예:
typedef int fun_t(void); typedef const fun_t const_qual_fun_t; // <= typedef const fun_t * ptr_to_const_qual_fun_t; // <= void foo() { const fun_t c_fun_t; // <= const fun_t * ptr_c_fun_t; // <= }
이 진단 규칙에 대한 자세한 내용은 설명서를 확인하세요.
리팩토링 및 디버깅 시 도움이 될 수 있는 C 언어에 대한 또 다른 진단 규칙입니다.
이 규칙을 사용하면 분석기가 정수 유형의 열거형 유형에 대한 암시적 캐스트를 감지할 수 있습니다.
PVS-Studio 경고가 포함된 코드 예:
void SomeCheck(const char *val) { if (!val) throw std::runtime_error { "" }; .... } void Foo() { const char *val = ....; try { SomeCheck(val); // <= } catch(std::runtime_error &err) { std::cerr << err.what() << std::endl; } }
이 코드는 조건 연산자(?:)를 사용하여 두 정수 변수 posOne과 posTwo 중에서 선택하여 암시적 캐스트를 생성합니다.
이 진단 규칙에 대한 자세한 내용은 설명서를 확인하세요.
다음은 SAST 원칙에 부합하는 보안에 초점을 맞춘 새로운 진단 규칙입니다.
이 규칙은 OWASP 보안 검증 표준에 따라 설계되었습니다.
오래된 암호화 기능 호출을 감지하는 것이 목표입니다. 이를 사용하면 심각한 소프트웨어 보안 문제가 발생할 수 있습니다.
PVS-Studio 경고가 포함된 코드 예:
typedef int fun_t(void); typedef const fun_t const_qual_fun_t; // <= typedef const fun_t * ptr_to_const_qual_fun_t; // <= void foo() { const fun_t c_fun_t; // <= const fun_t * ptr_c_fun_t; // <= }
Microsoft 설명서에 따르면 CryptoImportKey 및 CryptoDestroyKey 기능은 더 이상 사용되지 않습니다. 이는 Cryptography Next Generation의 보안 대응 항목(BCryptoImportKey 및 BCryptoDestroyKey)으로 대체되어야 합니다.
이 진단 규칙에 대한 자세한 내용은 설명서를 확인하세요.
하지만 그건 단지 워밍업일 뿐이에요! C 및 C 팀은 다양한 소프트웨어 개발 표준에 대한 더 많은 진단 규칙을 다룰 계획입니다. MISRA 표준에 특별한 주의를 기울일 것입니다. 그럼 소식을 기다려주세요 :)
새 PVS-Studio 7.34 릴리스에서 C# 팀은 Unity 관련 진단 규칙을 만드는 데 중점을 두었지만 일반 분석 규칙도 잊지 않았습니다.
후자부터 시작해 보겠습니다.
이 새로운 진단 규칙은 A 또는 B가 아닌 패턴의 잘못된 사용을 감지하는 것을 목표로 합니다. 문제는 개발자의 연산 우선순위에 대한 혼란에서 비롯됩니다.
PVS-Studio 경고가 포함된 코드 예:
Orientation GetOrientation (bool b) { int posOne = 1; int posTwo = 2; return b ? posOne : posTwo; // V2022 }
메서드 시작 시 입력 매개변수 키에 빈 문자열 또는 null이 있는지 확인합니다.
그런데 조건식의 논리에 오류가 있습니다. not 연산자의 우선순위는 or 연산자의 우선순위보다 높습니다. 결과적으로 부정은 표현식의 오른쪽에 적용되지 않습니다. 또한 키가 null로 설정되어 있으면 조건이 true가 됩니다.
이 진단 규칙에 대한 자세한 내용은 설명서를 확인하세요.
이것은 새로운 Unity 관련 규칙 시리즈 중 첫 번째 진단 규칙입니다.
System.WeakReference와 함께 UnityEngine.Object(또는 여기에서 상속된 다른 개체)의 사용을 감지하는 것을 목표로 합니다.
엔진 자체에서 암시적으로 인스턴스를 사용하기 때문에 약한 참조의 동작이 예상한 것과 다를 수 있습니다.
PVS-Studio 경고가 포함된 코드 예:
void SomeCheck(const char *val) { if (!val) throw std::runtime_error { "" }; .... } void Foo() { const char *val = ....; try { SomeCheck(val); // <= } catch(std::runtime_error &err) { std::cerr << err.what() << std::endl; } }
예제에서는 GameObject 클래스의 개체에 대한 약한 참조를 볼 수 있습니다. 작성자가 이 개체에 대한 강력한 참조를 생성하지 않은 경우에도 가비지 수집기가 해당 개체를 정리할 수 없습니다.
이 진단 규칙에 대한 자세한 내용은 설명서를 확인하세요.
Unity의 또 다른 진단 규칙에서 분석기는 wait 연산자를 사용하여 동일한 UnityEngine.Awaitable 개체를 여러 번 사용하는 장소를 검색합니다.
개체는 최적화 목적으로 개체 풀에 저장됩니다.
통화 대기 시 Awaitable 개체가 풀로 반환됩니다. 그 후 동일한 객체에 다시 Wait를 적용하면 예외가 발생합니다. 어떤 경우에는 교착상태가 발생할 수도 있습니다.
PVS-Studio 경고가 포함된 코드 예:
typedef int fun_t(void); typedef const fun_t const_qual_fun_t; // <= typedef const fun_t * ptr_to_const_qual_fun_t; // <= void foo() { const fun_t c_fun_t; // <= const fun_t * ptr_c_fun_t; // <= }
이 코드에서는 예외 또는 교착 상태가 발생합니다. 이유를 설명하겠습니다. 우리는 Waitable의 wait 호출을 사용하여 값을 얻습니다. 그런 다음 이 값으로 결과 변수를 초기화합니다. 조건부 구성에서 이전에 Wait가 Waitable에 적용되었으므로 교착 상태가 발생합니다.
이 진단 규칙에 대한 자세한 내용은 설명서를 확인하세요.
이 진단 규칙의 목적은 UnityEngine.Object 클래스의 Destroy 또는 DestroyImmediate 메서드 호출과 관련된 이상 현상을 탐지하는 것입니다.
UnityEngine.Transform 유형의 인수를 사용하는 상황에서 문제가 발생합니다. 이로 인해 메서드 호출 중에 오류가 발생합니다. Unity에서는 게임 개체에서 Transform 구성 요소를 제거하는 것이 허용되지 않습니다.
PVS-Studio 경고가 포함된 코드 예:
Orientation GetOrientation (bool b) { int posOne = 1; int posTwo = 2; return b ? posOne : posTwo; // V2022 }
MonoBehaviour 기본 클래스의 변환 속성은 Destroy 메서드에 인수로 전달되는 Transform 클래스의 인스턴스를 반환합니다.
이런 방식으로 메소드를 호출하면 Unity에서는 오류 메시지를 표시하지만 컴포넌트 자체는 삭제되지 않습니다.
이 진단 규칙에 대한 자세한 내용은 설명서를 확인하세요.
이 진단 규칙은 다양한 범위의 오류, 즉 성능 문제를 대상으로 합니다.
정적 분석이 Unity 프로젝트 최적화에 어떻게 도움이 되는지 관심이 있다면 이 기사를 읽어보시기 바랍니다.
이 규칙의 목적은 분석기가 자주 실행되는 메서드에서 Unity 객체 생성을 감지하도록 돕는 것입니다.
게임 개체의 정기적인 생성/파괴는 CPU에 부하를 줄 뿐만 아니라 가비지 수집기 호출 빈도도 증가시킵니다. 이는 성능에 영향을 미칩니다.
PVS-Studio 경고가 포함된 코드 예:
void SomeCheck(const char *val) { if (!val) throw std::runtime_error { "" }; .... } void Foo() { const char *val = ....; try { SomeCheck(val); // <= } catch(std::runtime_error &err) { std::cerr << err.what() << std::endl; } }
여기 Update 메서드에서는 게임 개체 _instance가 생성되고 삭제됩니다. Update는 프레임이 업데이트될 때마다 실행되므로, 가능하면 이러한 작업은 피하는 것이 좋습니다.
이 진단 규칙에 대한 자세한 내용은 설명서를 확인하세요.
그런데 다른 Unity 진단 기능은 아직 제공되지 않았습니다! 저희 팀이 전하는 좋은 소식을 받아보세요 :)
C# 분석기의 중요한 개선 사항 중 하나는 호출 간 메서드 반환 값의 변경 사항을 추적하는 것입니다. 무엇이 바뀌나요? 분해해 보겠습니다.
다음 예를 확인하세요.
typedef int fun_t(void); typedef const fun_t const_qual_fun_t; // <= typedef const fun_t * ptr_to_const_qual_fun_t; // <= void foo() { const fun_t c_fun_t; // <= const fun_t * ptr_c_fun_t; // <= }
Example() 메서드는 Foo()의 반환 값이 null인지 확인합니다. 그런 다음 조건 본문에서 Foo() 메서드가 다시 호출되고 해당 반환 값이 역참조됩니다.
이전에는 분석기가 호출 컨텍스트를 고려하지 않고 선언 코드에만 초점을 맞추기 때문에 이 경우 경고를 생성했습니다. null이 반환될 수 있음을 암시하는 데 사용되는 분석기입니다.
이제 분석기는 Foo()가 두 경우 모두 동일한 값을 반환하며 경고가 없다는 것을 이해합니다.
그런데 코드를 약간 수정한 예를 살펴보겠습니다...
Orientation GetOrientation (bool b) { int posOne = 1; int posTwo = 2; return b ? posOne : posTwo; // V2022 }
Foo() 메소드 선언에서 _condition == true일 때 메소드가 null이 아님을 반환한다는 것을 알 수 있습니다.
분석기는 두 번째 호출 전에 _condition 필드 변경을 확인하고 Foo() 내부에 사용된 필드가 변경된 경우 Foo()의 반환 값도 변경되었을 수 있다고 가정합니다.
결과적으로 역참조 가능성에 대한 경고가 유지됩니다.
이제 C# 분석기가 .NET 9 프로젝트 분석을 지원합니다! 여기에서 PVS-Studio 7.34의 이러한 기능과 기타 새로운 기능에 대해 자세히 알아보세요.
PVS-Studio 7.34가 출시되면서 이제 Java 분석기에 오염 분석 메커니즘이 생겼습니다!
이 메커니즘은 SQL 주입 검색이라는 첫 번째 진단 규칙의 기초가 되었습니다. Java 분석기의 향후 업데이트는 SAST, 가장 일반적인 잠재적 취약점이 포함된 OWASP 상위 10개 목록 및 기타 오염 관련 진단 규칙에 중점을 둘 것입니다.
지금은 가치가 있는 몇 가지 새로운 일반 분석 규칙부터 시작하겠습니다.
이 새로운 진단 규칙은 후위 연산 값이 사용되지 않는 코드 영역을 강조합니다.
문제는 작업이 중복되거나 더 심각하게는 작업이 혼동되어 개발자가 접두사 1을 사용하고 싶어한다는 것입니다.
PVS-Studio 경고가 포함된 코드 예:
void SomeCheck(const char *val) { if (!val) throw std::runtime_error { "" }; .... } void Foo() { const char *val = ....; try { SomeCheck(val); // <= } catch(std::runtime_error &err) { std::cerr << err.what() << std::endl; } }
연산자는calculateSomething 메소드가 반환하는 값에 영향을 주지 않습니다.
이 진단 규칙에 대한 자세한 내용은 설명서를 확인하세요.
이 진단 규칙의 이름에서 알 수 있듯이 오버플로 가능성을 감지합니다.
PVS-Studio 경고가 포함된 코드 예:
typedef int fun_t(void); typedef const fun_t const_qual_fun_t; // <= typedef const fun_t * ptr_to_const_qual_fun_t; // <= void foo() { const fun_t c_fun_t; // <= const fun_t * ptr_c_fun_t; // <= }
정수형 변수에 유효한 범위를 벗어난 값이 할당되어 오버플로가 발생합니다.
변수는 분명히 개발자가 할당하려고 시도한 값과 다른 값을 저장합니다.
이 진단 규칙에 대한 자세한 내용은 설명서를 확인하세요.
이 진단은 동기화 문제를 식별하는 데 도움이 됩니다.
PVS-Studio 경고가 포함된 코드 예:
Orientation GetOrientation (bool b) { int posOne = 1; int posTwo = 2; return b ? posOne : posTwo; // V2022 }
분석기는 동기화되지 않은 컨텍스트에서 호출될 수 있는 wait, inform 및 informAll 메소드를 포착합니다. 동기화가 발생하는 개체의 모니터와 함께 작동합니다. 즉, 해당 호출은 동기화된 컨텍스트와 동기화가 발생하는 개체에서만 정확합니다.
wait, inform 또는 informAll 메소드가 동기화되지 않은 컨텍스트나 잘못된 객체에서 호출되면 IllegalMonitorStateException 예외가 발생합니다.
이 진단 규칙에 대한 자세한 내용은 설명서를 확인하세요.
Java 분석기의 첫 번째 Taint 관련 진단 규칙! 더 구체적으로 말하면, 이제 분석기는 잠재적인 SQL 주입을 감지할 수 있습니다.
SQL 주입은 공격자가 자신의 코드를 SQL 쿼리에 주입할 수 있는 취약점입니다. 쿼리가 외부 데이터를 사용하는 경우 이를 올바르게 검증하지 않으면 데이터베이스에 저장된 정보의 무결성과 기밀성이 위험해질 수 있습니다.
void SomeCheck(const char *val) { if (!val) throw std::runtime_error { "" }; .... } void Foo() { const char *val = ....; try { SomeCheck(val); // <= } catch(std::runtime_error &err) { std::cerr << err.what() << std::endl; } }
사용자가 악의적인 것으로 판명되고 param의 값이 대략 다음과 같은 경우:- "111' 또는 1=1; 테이블 사용자 삭제; ' "를 선택하면 사용자 테이블과 작별할 수 있습니다. 따라서 외부 데이터를 확인하는 것이 중요합니다.
이 진단 규칙에 대한 자세한 내용은 설명서를 확인하세요.
읽어주셔서 감사합니다!
기사 요청이나 질문이 있는 경우 주저하지 말고 피드백 양식을 통해 보내주세요. 마지막으로, 댓글로 여러분의 생각을 듣고 싶습니다. :)
위 내용은 PVS-Studio 4의 새로운 진단 규칙의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!