Ошибки, которые сложно заметить на code review
но которые находятся
статическими анализаторами
DevRel
Андрей Карпов
Байка для разминки: DllMain
2
В любом случае никогда не выполняйте следующие задачи в пределах
функции DllMain:
 Вызов LoadLibrary или LoadLibraryEx (напрямую или косвенно). Это может привести к взаимной блокировке потоков или аварийному завершению программы.
 Вызов GetStringTypeA, GetStringTypeEx или GetStringTypeW (напрямую или косвенно). Это может привести к взаимной блокировке потоков или аварийному
завершению программы.
 Синхронизация с другими потоками. Это может привести к их взаимной блокировке.
 Захват объекта синхронизации, принадлежащего коду, который находится в ожидании захвата блокировки загрузчика. Это может привести к взаимной
блокировке потоков.
 Инициализация COM-потоков с помощью CoInitializeEx. При определенных условиях данная функция может вызвать LoadLibraryEx.
 Вызов реестровых функций. Данные функции реализованы в Advapi32.dll. Если Advapi32.dll не была инициализирована раньше пользовательской DLL-
библиотеки, последняя может обратиться к неинициализированной области памяти, что приведет к аварийному завершению процесса.
 Вызов CreateProcess. Создание процесса может повлечь за собой загрузку другой DLL-библиотеки.
 Вызов ExitThread. Выход из потока во время отсоединения DLL-библиотеки может повлечь за собой повторный захват блокировки загрузчика, что приведет к
взаимной блокировке потоков или аварийному завершению программы.
 Вызов CreateThread. Если создаваемый поток не синхронизируется с другими потоками, то такая операция допустима, хотя и рискованна.
 Создание именованного конвейера или другого именованного объекта (только для Windows 2000). В Windows 2000 именованные объекты предоставляются
библиотекой Terminal Services DLL. Если данная библиотека не инициализирована, ее вызовы могут привести к аварийному завершению процесса.
 Использование функций управления памятью из динамической библиотеки C Run-Time (CRT). Если данная библиотека не инициализирована, вызовы этих
функций могут привести к аварийному завершению процесса.
 Вызов функций из библиотек User32.dll или Gdi32.dll. Некоторые функции загружают другие DLL-библиотеки, которые могут быть не инициализированы.
Байка для разминки (читать не надо)
3
Андрей Карпов
Присутствую на Habr под именем Andrey2008
habr.com/ru/users/andrey2008/
Один из основателей проекта PVS-Studio
www.pvs-studio.com
4
Докладчик
5
Как статический анализ дополняет обзоры
кода
 Неприметные ошибки (обычно опечатки)
 Ошибки в коде, на котором люди не могут сосредоточиться
 Программисты что-то не знают
Неприметные ошибки
6
Опечатка при Copy-Paste
7
EA WebKit, С++
value.start_fragment_union_rect.size.width =
std::max(descendant.offset_to_container_box.left +
descendant.fragment->Size().width -
value.start_fragment_union_rect.offset.left,
value.start_fragment_union_rect.size.width);
value.start_fragment_union_rect.size.height =
std::max(descendant.offset_to_container_box.top +
descendant.fragment->Size().height -
value.start_fragment_union_rect.offset.top,
value.start_fragment_union_rect.size.width);
Опечатка при Copy-Paste
8
PVS-Studio: V778 CWE-682 Two similar code fragments were found. Perhaps, this
is a typo and 'height' variable should be used instead of 'width'.
EA WebKit, С++
value.start_fragment_union_rect.size.width =
std::max(descendant.offset_to_container_box.left +
descendant.fragment->Size().width -
value.start_fragment_union_rect.offset.left,
value.start_fragment_union_rect.size.width);
value.start_fragment_union_rect.size.height =
std::max(descendant.offset_to_container_box.top +
descendant.fragment->Size().height -
value.start_fragment_union_rect.offset.top,
value.start_fragment_union_rect.size.width);
Плохое хеширование
9
Open Graph Drawing Framework,
C++
template<> class DefHashFunc<void *> {
public:
size_t hash(const void * &key) const
{ return size_t(key && 0xffffffff); }
};
Плохое хеширование
10
Open Graph Drawing Framework,
C++
PVS-Studio: V560 A part of conditional expression is always true: 0xffffffff.
hashing.h 255
template<> class DefHashFunc<void *> {
public:
size_t hash(const void * &key) const
{ return size_t(key && 0xffffffff); }
};
& – побитовый AND / && – логический AND
Пропустили запятую
11
Linux Kernel, C
static ssize_t lp8788_show_eoc_time(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct lp8788_charger *pchg = dev_get_drvdata(dev);
char *stime[] = { "400ms", "5min", "10min", "15min",
"20min", "25min", "30min" "No timeout" };
....
}
PVS-Studio: V653 A suspicious string consisting of two parts is
used for array initialization. It is possible that a comma is
missing. Consider inspecting this literal: "30min" "No timeout".
lp8788-charger.c 657
12
Ошибки в коде, на котором люди не могут
сосредоточиться
Бла-бла код
13
Hibernate, Java
Бла-бла код
14
private static final Map<Class, String> annotationToXml;
....
annotationToXml.put(AttributeOverride.class, "attribute-override");
....
annotationToXml.put(AttributeOverride.class, "association-override");
....
annotationToXml.put(AttributeOverride.class, "map-key-attribute-override");
• V6033 An item with the same key 'javax.persistence.AttributeOverride.class' has
already been added. Check lines: 188, 186. JPAOverriddenAnnotationReader.java
188
• V6033 An item with the same key 'javax.persistence.AttributeOverride.class' has
already been added. Check lines: 190, 186. JPAOverriddenAnnotationReader.java
190
Hibernate, Java
 Даже статью написал “Зло живёт в функциях сравнения”
https://pvs-studio.ru/ru/blog/posts/cpp/0509/
Паттерн: не проверяют функции сравнения
15
Функции сравнения
16
PVS-Studio: V501 There are
identical sub-expressions to
the left and to the right of the
'==' operator: AutoWritable ==
AutoWritable
rendererinterface.h 180
Unreal Engine 4, C++
bool Compare(const FPooledRenderTargetDesc& rhs, bool bExact) const
{
....
return Extent == rhs.Extent
&& Depth == rhs.Depth
&& bIsArray == rhs.bIsArray
&& ArraySize == rhs.ArraySize
&& NumMips == rhs.NumMips
&& NumSamples == rhs.NumSamples
&& Format == rhs.Format
&& LhsFlags == RhsFlags
&& TargetableFlags == rhs.TargetableFlags
&& bForceSeparateTargetAndShaderResource ==
rhs.bForceSeparateTargetAndShaderResource
&& ClearValue == rhs.ClearValue
&& AutoWritable == AutoWritable;
}
Функции сравнения
17
public boolean equals(Object other) {
if (other instanceof Id) {
Id that = (Id) other;
return purchaseSequence.equals(this.purchaseSequence) &&
that.purchaseNumber == this.purchaseNumber;
}
else {
return false;
}
}
PVS-Studio: V6009 Function 'equals' receives odd arguments. Inspect first argument.
PurchaseRecord.java 57
Hibernate, Java
Программисты что-то не знают
18
CWE-14: Компилятор удаляет код для
затирания буфера
SECStatus
SHA384_HashBuf(unsigned char *dest, const unsigned char *src,
PRUint32 src_length)
{
SHA512Context ctx;
unsigned int outLen;
SHA384_Begin(&ctx);
SHA512_Update(&ctx, src, src_length);
SHA512_End(&ctx, dest, &outLen, SHA384_LENGTH);
memset(&ctx, 0, sizeof ctx);
return SECSuccess;
}
PVS-Studio: V597 CWE-14 The compiler could delete the
'memset' function call, which is used to flush 'ctx' object.
Network Security Services (NSS), C
20
CWE-14: Компилятор удаляет код для
затирания буфера
 Подробнее: https://cwe.mitre.org/data/definitions/14.html
 При отладке Debug-версии этой ошибки нет
 Если не знаешь про этот паттерн, то нельзя найти ошибку
во время обзора кода
 Невозможно написать тест, если не искать эту ошибку
целенаправленно
 Эта ошибка везде. Я находил её в таких проектах, как:
Sphinx, XNU kernel, MySQL, Tizen, FreeBSD Kernel, Linux
Kernel, Haiku Operation System, Qt, Apache HTTP Server и
т.д.
Кто видит ошибку?
21
char c;
printf("%s is already in *.base_fs format, just copying ....);
rewind(blk_alloc_file);
while ((c = fgetc(blk_alloc_file)) != EOF) {
fputc(c, base_fs_file);
}
Android, C
Windows
кодировка
CP1251.
Буква 'я' имеет
код 255.
22
Злоключения буквы 'я'
23
char c;
printf("%s is already in *.base_fs format, just copying ....);
rewind(blk_alloc_file);
while ((c = fgetc(blk_alloc_file)) != EOF) {
fputc(c, base_fs_file);
}
Android, C
PVS-Studio: V739 CWE-20 EOF should not be compared with a value of the 'char'
type. The '(c = fgetc(blk_alloc_file))' should be of the 'int' type.
blk_alloc_to_base_fs.c 61
Хождение по тонкому льду
24
Oracle MySQL 5.1.x,
C
CVE-2012-2122 (Не мы нашли, но могли бы)
PVS-Studio: V642 Saving the 'memcmp' function result inside the 'char' type variable is
inappropriate. The significant bits could be lost breaking the program's logic.
password.c
typedef char my_bool;
my_bool
check_scramble(const char *scramble_arg, const char *message,
const uint8 *hash_stage2)
{
....
return memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE);
}
24
25
PUGI__FN bool set_value_convert(char_t*& dest, uintptr_t& header,
uintptr_t header_mask, int value)
{
char buf[128];
sprintf(buf, "%d", value);
return set_value_buffer(dest, header, header_mask, buf);
}
StarEngine, C++
26
#define sfstream std::fstream
#define schar char
#define suchar unsigned schar
#define sprintf std::printf
#define satof atof
#define satoi atoi
PUGI__FN bool set_value_convert(char_t*& dest, uintptr_t& header,
uintptr_t header_mask, int value)
{
char buf[128];
sprintf(buf, "%d", value);
return set_value_buffer(dest, header, header_mask, buf);
}
PVS-Studio: V614 Uninitialized buffer 'buf' used. pugixml.cpp 3362
StarEngine, C++
27
Статический анализ дополняет и
unit-тестирование
Ошибки в тестах
28
Entity Framework, C#
PVS-Studio: V3081 The 'j' counter is not used inside a nested
loop. Consider inspecting usage of 'i' counter.
EFCore.Specification.Tests
ComplexNavigationsQueryTestBase.cs 2393
for (var i = 0; i < result.Count; i++)
{
....
for (var j = 0; j < expectedInnerNames.Count; j++)
{
Assert.True(
result[i]
.OneToMany_Optional.Select(e => e.Name)
.Contains(expectedInnerNames[i])
);
}
}
Ошибки в тестах
29
.NET Compiler Platform ("Roslyn"),
C#
PVS-Studio: V3004 The 'then' statement is
equivalent to the 'else' statement.
GetSemanticInfoTests.cs 2269
for (int i = 0; i < 20; i++)
{
....
if (i % 2 == 0)
{
thread1.Start();
thread2.Start();
}
else
{
thread1.Start();
thread2.Start();
}
....
 С, C++, C#, Java
 Промокод: tashkent2023
Скачать и попробовать PVS-Studio
30
Q&A
pvs-studio.com
31
karpov@viva64.com
32
static const int kDaysInMonth[13] = {
0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
bool ValidateDateTime(const DateTime& time) {
if (time.year < 1 || time.year > 9999 ||
time.month < 1 || time.month > 12 ||
time.day < 1 || time.day > 31 ||
time.hour < 0 || time.hour > 23 ||
time.minute < 0 || time.minute > 59 ||
time.second < 0 || time.second > 59) {
return false;
}
if (time.month == 2 && IsLeapYear(time.year)) {
return time.month <= kDaysInMonth[time.month] + 1;
} else {
return time.month <= kDaysInMonth[time.month];
}
}
33
static const int kDaysInMonth[13] = {
0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
bool ValidateDateTime(const DateTime& time) {
if (time.year < 1 || time.year > 9999 ||
time.month < 1 || time.month > 12 ||
time.day < 1 || time.day > 31 ||
time.hour < 0 || time.hour > 23 ||
time.minute < 0 || time.minute > 59 ||
time.second < 0 || time.second > 59) {
return false;
}
if (time.month == 2 && IsLeapYear(time.year)) {
return time.month <= kDaysInMonth[time.month] + 1;
} else {
return time.month <= kDaysInMonth[time.month];
}
}
34
static const int kDaysInMonth[13] = {
0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
bool ValidateDateTime(const DateTime& time) {
if (time.year < 1 || time.year > 9999 ||
time.month < 1 || time.month > 12 ||
time.day < 1 || time.day > 31 ||
time.hour < 0 || time.hour > 23 ||
time.minute < 0 || time.minute > 59 ||
time.second < 0 || time.second > 59) {
return false;
}
if (time.month == 2 && IsLeapYear(time.year)) {
return time.month <= kDaysInMonth[time.month] + 1;
} else {
return time.month <= kDaysInMonth[time.month];
}
}
static const int kDaysInMonth[13] = {
0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
bool ValidateDateTime(const DateTime& time) {
if (time.year < 1 || time.year > 9999 ||
time.month < 1 || time.month > 12 ||
time.day < 1 || time.day > 31 ||
time.hour < 0 || time.hour > 23 ||
time.minute < 0 || time.minute > 59 ||
time.second < 0 || time.second > 59) {
return false;
}
if (time.month == 2 && IsLeapYear(time.year)) {
return time.month <= kDaysInMonth[time.month] + 1;
} else {
return time.month <= kDaysInMonth[time.month];
}
} time.day
Protobuf, C
36
class FMallocBinned : public FMalloc
{
uint64 PoolMask;
....
FMallocBinned(uint32 InPageSize, uint64 AddressLimit)
{
....
PoolMask = (( 1 << ( HashKeyShift - PoolBitShift ) ) - 1);
....
}
};
PVS-Studio: V629 Consider inspecting the '1 << (HashKeyShift -
PoolBitShift)' expression. Bit shifting of the 32-bit value with a subsequent
expansion to the 64-bit type. mallocbinned.h 800
Unreal Engine 4, C++
37
class FMallocBinned : public FMalloc
{
uint64 PoolMask;
....
FMallocBinned(uint32 InPageSize, uint64 AddressLimit)
{
....
PoolMask = (( 1ULL << ( HashKeyShift - PoolBitShift ) ) - 1);
....
}
};
Unreal Engine 4, C++
38
Jenkins, Java
PVS-Studio: V6007 Expression 'cnt < 5' is always true. AbstractProject.java 557
public final R getSomeBuildWithWorkspace() {
int cnt=0;
for (R b = getLastBuild(); cnt<5 && b!=null; b=b.getPreviousBuild())
{
FilePath ws = b.getWorkspace();
if (ws!=null) return b;
}
return null;
}
39
FreeBSD Kernel,
C
PVS-Studio: V621 Consider inspecting the 'for' operator. It's possible that the loop will
be executed incorrectly or won't be executed at all. if_ae.c 1663
#define AE_IDLE_TIMEOUT 100
....
int i;
....
/* Wait for IDLE state. */
for (i = 0; i < AE_IDLE_TIMEOUT; i--) {
val = AE_READ_4(sc, AE_IDLE_REG);
if ((val & (AE_IDLE_RXMAC | AE_IDLE_DMAWRITE)) == 0)
break;
DELAY(100);
}
40

Ошибки, которые сложно заметить на code review, но которые находятся статическими анализаторами

  • 1.
    Ошибки, которые сложнозаметить на code review но которые находятся статическими анализаторами DevRel Андрей Карпов
  • 2.
  • 3.
    В любом случаеникогда не выполняйте следующие задачи в пределах функции DllMain:  Вызов LoadLibrary или LoadLibraryEx (напрямую или косвенно). Это может привести к взаимной блокировке потоков или аварийному завершению программы.  Вызов GetStringTypeA, GetStringTypeEx или GetStringTypeW (напрямую или косвенно). Это может привести к взаимной блокировке потоков или аварийному завершению программы.  Синхронизация с другими потоками. Это может привести к их взаимной блокировке.  Захват объекта синхронизации, принадлежащего коду, который находится в ожидании захвата блокировки загрузчика. Это может привести к взаимной блокировке потоков.  Инициализация COM-потоков с помощью CoInitializeEx. При определенных условиях данная функция может вызвать LoadLibraryEx.  Вызов реестровых функций. Данные функции реализованы в Advapi32.dll. Если Advapi32.dll не была инициализирована раньше пользовательской DLL- библиотеки, последняя может обратиться к неинициализированной области памяти, что приведет к аварийному завершению процесса.  Вызов CreateProcess. Создание процесса может повлечь за собой загрузку другой DLL-библиотеки.  Вызов ExitThread. Выход из потока во время отсоединения DLL-библиотеки может повлечь за собой повторный захват блокировки загрузчика, что приведет к взаимной блокировке потоков или аварийному завершению программы.  Вызов CreateThread. Если создаваемый поток не синхронизируется с другими потоками, то такая операция допустима, хотя и рискованна.  Создание именованного конвейера или другого именованного объекта (только для Windows 2000). В Windows 2000 именованные объекты предоставляются библиотекой Terminal Services DLL. Если данная библиотека не инициализирована, ее вызовы могут привести к аварийному завершению процесса.  Использование функций управления памятью из динамической библиотеки C Run-Time (CRT). Если данная библиотека не инициализирована, вызовы этих функций могут привести к аварийному завершению процесса.  Вызов функций из библиотек User32.dll или Gdi32.dll. Некоторые функции загружают другие DLL-библиотеки, которые могут быть не инициализированы. Байка для разминки (читать не надо) 3
  • 4.
    Андрей Карпов Присутствую наHabr под именем Andrey2008 habr.com/ru/users/andrey2008/ Один из основателей проекта PVS-Studio www.pvs-studio.com 4 Докладчик
  • 5.
    5 Как статический анализдополняет обзоры кода  Неприметные ошибки (обычно опечатки)  Ошибки в коде, на котором люди не могут сосредоточиться  Программисты что-то не знают
  • 6.
  • 7.
    Опечатка при Copy-Paste 7 EAWebKit, С++ value.start_fragment_union_rect.size.width = std::max(descendant.offset_to_container_box.left + descendant.fragment->Size().width - value.start_fragment_union_rect.offset.left, value.start_fragment_union_rect.size.width); value.start_fragment_union_rect.size.height = std::max(descendant.offset_to_container_box.top + descendant.fragment->Size().height - value.start_fragment_union_rect.offset.top, value.start_fragment_union_rect.size.width);
  • 8.
    Опечатка при Copy-Paste 8 PVS-Studio:V778 CWE-682 Two similar code fragments were found. Perhaps, this is a typo and 'height' variable should be used instead of 'width'. EA WebKit, С++ value.start_fragment_union_rect.size.width = std::max(descendant.offset_to_container_box.left + descendant.fragment->Size().width - value.start_fragment_union_rect.offset.left, value.start_fragment_union_rect.size.width); value.start_fragment_union_rect.size.height = std::max(descendant.offset_to_container_box.top + descendant.fragment->Size().height - value.start_fragment_union_rect.offset.top, value.start_fragment_union_rect.size.width);
  • 9.
    Плохое хеширование 9 Open GraphDrawing Framework, C++ template<> class DefHashFunc<void *> { public: size_t hash(const void * &key) const { return size_t(key && 0xffffffff); } };
  • 10.
    Плохое хеширование 10 Open GraphDrawing Framework, C++ PVS-Studio: V560 A part of conditional expression is always true: 0xffffffff. hashing.h 255 template<> class DefHashFunc<void *> { public: size_t hash(const void * &key) const { return size_t(key && 0xffffffff); } }; & – побитовый AND / && – логический AND
  • 11.
    Пропустили запятую 11 Linux Kernel,C static ssize_t lp8788_show_eoc_time(struct device *dev, struct device_attribute *attr, char *buf) { struct lp8788_charger *pchg = dev_get_drvdata(dev); char *stime[] = { "400ms", "5min", "10min", "15min", "20min", "25min", "30min" "No timeout" }; .... } PVS-Studio: V653 A suspicious string consisting of two parts is used for array initialization. It is possible that a comma is missing. Consider inspecting this literal: "30min" "No timeout". lp8788-charger.c 657
  • 12.
    12 Ошибки в коде,на котором люди не могут сосредоточиться
  • 13.
  • 14.
    Бла-бла код 14 private staticfinal Map<Class, String> annotationToXml; .... annotationToXml.put(AttributeOverride.class, "attribute-override"); .... annotationToXml.put(AttributeOverride.class, "association-override"); .... annotationToXml.put(AttributeOverride.class, "map-key-attribute-override"); • V6033 An item with the same key 'javax.persistence.AttributeOverride.class' has already been added. Check lines: 188, 186. JPAOverriddenAnnotationReader.java 188 • V6033 An item with the same key 'javax.persistence.AttributeOverride.class' has already been added. Check lines: 190, 186. JPAOverriddenAnnotationReader.java 190 Hibernate, Java
  • 15.
     Даже статьюнаписал “Зло живёт в функциях сравнения” https://pvs-studio.ru/ru/blog/posts/cpp/0509/ Паттерн: не проверяют функции сравнения 15
  • 16.
    Функции сравнения 16 PVS-Studio: V501There are identical sub-expressions to the left and to the right of the '==' operator: AutoWritable == AutoWritable rendererinterface.h 180 Unreal Engine 4, C++ bool Compare(const FPooledRenderTargetDesc& rhs, bool bExact) const { .... return Extent == rhs.Extent && Depth == rhs.Depth && bIsArray == rhs.bIsArray && ArraySize == rhs.ArraySize && NumMips == rhs.NumMips && NumSamples == rhs.NumSamples && Format == rhs.Format && LhsFlags == RhsFlags && TargetableFlags == rhs.TargetableFlags && bForceSeparateTargetAndShaderResource == rhs.bForceSeparateTargetAndShaderResource && ClearValue == rhs.ClearValue && AutoWritable == AutoWritable; }
  • 17.
    Функции сравнения 17 public booleanequals(Object other) { if (other instanceof Id) { Id that = (Id) other; return purchaseSequence.equals(this.purchaseSequence) && that.purchaseNumber == this.purchaseNumber; } else { return false; } } PVS-Studio: V6009 Function 'equals' receives odd arguments. Inspect first argument. PurchaseRecord.java 57 Hibernate, Java
  • 18.
  • 19.
    CWE-14: Компилятор удаляеткод для затирания буфера SECStatus SHA384_HashBuf(unsigned char *dest, const unsigned char *src, PRUint32 src_length) { SHA512Context ctx; unsigned int outLen; SHA384_Begin(&ctx); SHA512_Update(&ctx, src, src_length); SHA512_End(&ctx, dest, &outLen, SHA384_LENGTH); memset(&ctx, 0, sizeof ctx); return SECSuccess; } PVS-Studio: V597 CWE-14 The compiler could delete the 'memset' function call, which is used to flush 'ctx' object. Network Security Services (NSS), C
  • 20.
    20 CWE-14: Компилятор удаляеткод для затирания буфера  Подробнее: https://cwe.mitre.org/data/definitions/14.html  При отладке Debug-версии этой ошибки нет  Если не знаешь про этот паттерн, то нельзя найти ошибку во время обзора кода  Невозможно написать тест, если не искать эту ошибку целенаправленно  Эта ошибка везде. Я находил её в таких проектах, как: Sphinx, XNU kernel, MySQL, Tizen, FreeBSD Kernel, Linux Kernel, Haiku Operation System, Qt, Apache HTTP Server и т.д.
  • 21.
    Кто видит ошибку? 21 charc; printf("%s is already in *.base_fs format, just copying ....); rewind(blk_alloc_file); while ((c = fgetc(blk_alloc_file)) != EOF) { fputc(c, base_fs_file); } Android, C
  • 22.
  • 23.
    Злоключения буквы 'я' 23 charc; printf("%s is already in *.base_fs format, just copying ....); rewind(blk_alloc_file); while ((c = fgetc(blk_alloc_file)) != EOF) { fputc(c, base_fs_file); } Android, C PVS-Studio: V739 CWE-20 EOF should not be compared with a value of the 'char' type. The '(c = fgetc(blk_alloc_file))' should be of the 'int' type. blk_alloc_to_base_fs.c 61
  • 24.
    Хождение по тонкомульду 24 Oracle MySQL 5.1.x, C CVE-2012-2122 (Не мы нашли, но могли бы) PVS-Studio: V642 Saving the 'memcmp' function result inside the 'char' type variable is inappropriate. The significant bits could be lost breaking the program's logic. password.c typedef char my_bool; my_bool check_scramble(const char *scramble_arg, const char *message, const uint8 *hash_stage2) { .... return memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE); } 24
  • 25.
    25 PUGI__FN bool set_value_convert(char_t*&dest, uintptr_t& header, uintptr_t header_mask, int value) { char buf[128]; sprintf(buf, "%d", value); return set_value_buffer(dest, header, header_mask, buf); } StarEngine, C++
  • 26.
    26 #define sfstream std::fstream #defineschar char #define suchar unsigned schar #define sprintf std::printf #define satof atof #define satoi atoi PUGI__FN bool set_value_convert(char_t*& dest, uintptr_t& header, uintptr_t header_mask, int value) { char buf[128]; sprintf(buf, "%d", value); return set_value_buffer(dest, header, header_mask, buf); } PVS-Studio: V614 Uninitialized buffer 'buf' used. pugixml.cpp 3362 StarEngine, C++
  • 27.
  • 28.
    Ошибки в тестах 28 EntityFramework, C# PVS-Studio: V3081 The 'j' counter is not used inside a nested loop. Consider inspecting usage of 'i' counter. EFCore.Specification.Tests ComplexNavigationsQueryTestBase.cs 2393 for (var i = 0; i < result.Count; i++) { .... for (var j = 0; j < expectedInnerNames.Count; j++) { Assert.True( result[i] .OneToMany_Optional.Select(e => e.Name) .Contains(expectedInnerNames[i]) ); } }
  • 29.
    Ошибки в тестах 29 .NETCompiler Platform ("Roslyn"), C# PVS-Studio: V3004 The 'then' statement is equivalent to the 'else' statement. GetSemanticInfoTests.cs 2269 for (int i = 0; i < 20; i++) { .... if (i % 2 == 0) { thread1.Start(); thread2.Start(); } else { thread1.Start(); thread2.Start(); } ....
  • 30.
     С, C++,C#, Java  Промокод: tashkent2023 Скачать и попробовать PVS-Studio 30
  • 31.
  • 32.
    32 static const intkDaysInMonth[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; bool ValidateDateTime(const DateTime& time) { if (time.year < 1 || time.year > 9999 || time.month < 1 || time.month > 12 || time.day < 1 || time.day > 31 || time.hour < 0 || time.hour > 23 || time.minute < 0 || time.minute > 59 || time.second < 0 || time.second > 59) { return false; } if (time.month == 2 && IsLeapYear(time.year)) { return time.month <= kDaysInMonth[time.month] + 1; } else { return time.month <= kDaysInMonth[time.month]; } }
  • 33.
    33 static const intkDaysInMonth[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; bool ValidateDateTime(const DateTime& time) { if (time.year < 1 || time.year > 9999 || time.month < 1 || time.month > 12 || time.day < 1 || time.day > 31 || time.hour < 0 || time.hour > 23 || time.minute < 0 || time.minute > 59 || time.second < 0 || time.second > 59) { return false; } if (time.month == 2 && IsLeapYear(time.year)) { return time.month <= kDaysInMonth[time.month] + 1; } else { return time.month <= kDaysInMonth[time.month]; } }
  • 34.
    34 static const intkDaysInMonth[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; bool ValidateDateTime(const DateTime& time) { if (time.year < 1 || time.year > 9999 || time.month < 1 || time.month > 12 || time.day < 1 || time.day > 31 || time.hour < 0 || time.hour > 23 || time.minute < 0 || time.minute > 59 || time.second < 0 || time.second > 59) { return false; } if (time.month == 2 && IsLeapYear(time.year)) { return time.month <= kDaysInMonth[time.month] + 1; } else { return time.month <= kDaysInMonth[time.month]; } }
  • 35.
    static const intkDaysInMonth[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; bool ValidateDateTime(const DateTime& time) { if (time.year < 1 || time.year > 9999 || time.month < 1 || time.month > 12 || time.day < 1 || time.day > 31 || time.hour < 0 || time.hour > 23 || time.minute < 0 || time.minute > 59 || time.second < 0 || time.second > 59) { return false; } if (time.month == 2 && IsLeapYear(time.year)) { return time.month <= kDaysInMonth[time.month] + 1; } else { return time.month <= kDaysInMonth[time.month]; } } time.day Protobuf, C
  • 36.
    36 class FMallocBinned :public FMalloc { uint64 PoolMask; .... FMallocBinned(uint32 InPageSize, uint64 AddressLimit) { .... PoolMask = (( 1 << ( HashKeyShift - PoolBitShift ) ) - 1); .... } }; PVS-Studio: V629 Consider inspecting the '1 << (HashKeyShift - PoolBitShift)' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. mallocbinned.h 800 Unreal Engine 4, C++
  • 37.
    37 class FMallocBinned :public FMalloc { uint64 PoolMask; .... FMallocBinned(uint32 InPageSize, uint64 AddressLimit) { .... PoolMask = (( 1ULL << ( HashKeyShift - PoolBitShift ) ) - 1); .... } }; Unreal Engine 4, C++
  • 38.
    38 Jenkins, Java PVS-Studio: V6007Expression 'cnt < 5' is always true. AbstractProject.java 557 public final R getSomeBuildWithWorkspace() { int cnt=0; for (R b = getLastBuild(); cnt<5 && b!=null; b=b.getPreviousBuild()) { FilePath ws = b.getWorkspace(); if (ws!=null) return b; } return null; }
  • 39.
    39 FreeBSD Kernel, C PVS-Studio: V621Consider inspecting the 'for' operator. It's possible that the loop will be executed incorrectly or won't be executed at all. if_ae.c 1663 #define AE_IDLE_TIMEOUT 100 .... int i; .... /* Wait for IDLE state. */ for (i = 0; i < AE_IDLE_TIMEOUT; i--) { val = AE_READ_4(sc, AE_IDLE_REG); if ((val & (AE_IDLE_RXMAC | AE_IDLE_DMAWRITE)) == 0) break; DELAY(100); }
  • 40.