﻿# Эксперимент по поиску ошибок в коде C\# компонентов Tizen

Недавно ко мне обратился мой коллега, Андрей Карпов, с просьбой попробовать найти 3\-4 ошибки в коде компонентов Tizen на языке C\#\. Сам он не так давно занимался анализом Tizen на предмет поиска ошибок в C/C\+\+ коде и сейчас пишет несколько статей на эту тему\. Вдохновлённый его примером, я провёл эксперимент по поиску ошибок в C\# компонентах Tizen\. Сразу скажу, что эксперимент прошел удачно, и в дальнейшем я займусь написанием большой статьи на эту тему, а сейчас просто поделюсь результатами пробной проверки\.

![0518_Tizen_Cs_ru/image1.png](https://import.viva64.com/docx/blog/0518_Tizen_Cs_ru/image1.png)

Для начала я не стал проводить глубокий анализ всей базы исходного кода Tizen, а выбрал пару проектов на языке C\#, проверка которых не потребовала бы особых усилий\. Цель нашего эксперимента – постараться понять, нужно ли работать в этом направлении\.

В результате даже такой поверхностной проверки мне довольно быстро удалось найти несколько реальных ошибок, что позволяет утверждать: здесь есть работа для C\# анализатора PVS\-Studio\. В данной короткой заметке я ограничусь описанием этих ошибок, оставив более подробное изучение данного вопроса на будущее\.

По моим подсчётам, код Tizen содержит 4 929 файлов исходного кода с расширением _cs_, в которых имеется около 691 000 строк кода\. Исходный код довольно объёмен и его полноценный анализ потребует некоторого времени\. Позже, по результатам этой работы, я напишу развёрнутую статью\.

Пока же приведу описание трёх из списка найденных мною на данном этапе работы ошибок\. Для простоты я буду указывать имя папки верхнего уровня в иерархии проектов Tizen, где содержался файл с ошибкой\.

**xamarin\-forms\-tizen** 

PVS\-Studio: [V3001](https://pvs-studio.ru/ru/docs/warnings/v3001/) There are identical sub\-expressions 'RwWait' to the left and to the right of the '\|' operator\. Xamarin\.Forms\.Platform\.WP8 SplitOrderedList\.cs 458

```cpp
struct SimpleRwLock
{
  const int RwWait = 1;
  const int RwWrite = 2;
  const int RwRead = 4;
  ....
  public void EnterReadLock()
  {
    var sw = new SpinWait();
    do
    {
      while ((_rwlock & (RwWrite | RwWait)) > 0)
        sw.SpinOnce();

      if ((Interlocked.Add(ref _rwlock, RwRead)
          & (RwWait | RwWait)) == 0)                // <=
        return;

      Interlocked.Add(ref _rwlock, -RwRead);
    } while (true);
  }
  ....
}
```

Вероятно, в условии блока _if_ допущена опечатка, связанная с похожестью имен констант _RwWait и RwWrite,_ в результате чего константа _RwWait_ была ошибочно использована дважды\. В пользу этого говорит и условие в блоке _while_ выше, где используется правильное сочетание _RwWrite \| RwWait_\.

PVS\-Studio: [V3095](https://pvs-studio.ru/ru/docs/warnings/v3095/) The 'type' object was used before it was verified against null\. Check lines: 147, 149\. Xamarin\.Forms\.Xaml ExpandMarkupsVisitor\.cs 147

CWE\-476 NULL Pointer Dereference

```cpp
public class MarkupExpansionParser : 
  MarkupExpressionParser, IExpressionParser<INode>
{
  ....
  public INode Parse(....)
  {
    ....
    Type type;
    ....
    var xmltype = new XmlType(namespaceuri, type.Name, null); // <=
   
    if (type == null)
      throw new NotSupportedException();
    ....
  }
  ....
}
```

Переменную _type_ сначала используют для доступа к _type\.Name_, а уже затем проверяют на равенство _null_\. В результате возможно возникновение исключения типа _NullReferenceException_\.

**csapi\-location**

PVS\-Studio\. [V3110](https://pvs-studio.ru/ru/docs/warnings/v3110/) Possible infinite recursion inside 'Timestamp' property\. Tizen\.Location Location\.cs 186

CWE\-674 Uncontrolled Recursion

```cpp
public class Location
{
  ....
  internal int _timestamp;
  ....
  public DateTime Timestamp
  {
    get
    {
        return Interop.ConvertDateTime(_timestamp);
    }
    internal set
    {
        Timestamp = value;             // <=
    }
  }  
  ....
}
```

Данный фрагмент кода содержит ошибку, неизбежно приводящую к исчерпанию стека \(бесконечная рекурсия\) при попытке доступа на запись к свойству _Timestamp_\. При этом нет видимых признаков опечатки\. Поле _\_timestamp_ значительно отличается по написанию от _Timestamp_, так что непохоже, что их могли перепутать\. К тому же, _\_timestamp_ имеет тип _int_, что делает невозможным прямое присвоение ему значения _value_ типа _DateTime_\. Потребовалось бы преобразование типа, наподобие того, что реализовано в секции _get_\. Думаю, исправить данную ошибку смог бы только автор\.

Думаю, для начала достаточно, остальные ошибки, найденные на этом этапе, я приберегу для следующей статьи\.

Можно сделать вывод, что анализатор PVS\-Studio может быть использован не только для проверки C и C\+\+ кода, но и для проверки компонентов, разработанных на C\#\. 

[Скачать и попробовать PVS\-Studio](https://pvs-studio.ru/ru/pvs-studio/)\.

Дополнительные ссылки:

1. [Команда PVS\-Studio готова поработать над проектом Tizen \(открытое письмо\)](https://pvs-studio.ru/ru/blog/posts/cpp/0508/)
1. [Предоставляем анализатор PVS\-Studio экспертам безопасности](https://pvs-studio.ru/ru/blog/posts/0510/)
1. [Как PVS\-Studio может помочь в поиске уязвимостей?](https://pvs-studio.ru/ru/blog/posts/cpp/0514/)
1. [PVS\-Studio как плагин для SonarQube](https://pvs-studio.ru/ru/blog/posts/0513/)