SlideShare une entreprise Scribd logo
1  sur  19
Télécharger pour lire hors ligne
PVS-Studio in the Clouds: Azure DevOps
Author: Oleg Andreev, Ilya Gainulin
Date: 13.09.2019
Tags: CSharp, DevOps
This is a second article, which focuses on usage of the PVS-Studio analyzer in cloud CI-systems. This time
we'll consider the platform Azure DevOps - a cloud CICD solution from Microsoft. We'll be analyzing the
ShareX project.
We'll need three components. The first is the PVS-Studio analyzer. The second is Azure DevOps, which we'll
integrate the analyzer with. The third is the project that we'll check in order to demonstrate the abilities of
PVS-Studio when working in a cloud. So let's get going.
PVS-Studio is a static code analyzer for finding errors and security defects. The tool supports the analysis of
C, C++ and C# code.
Azure DevOps. The Azure DevOps platform includes such tools as Azure Pipeline, Azure Board, Azure
Artifacts and others that speed up the process of creating software and improve its quality.
ShareX is a free app that lets you capture and record any part of the screen. The project is written in C# and
is eminently suitable to show configuration of the static analyzer launch. The project source code is
available on GitHub.
The output of the cloc command for the ShareX project:
Language files blank comment Code
C# 696 20658 24423 102565
MSBuild script 11 1 77 5859
In other words, the project is small, but quite sufficient to demonstrate the work of PVS-Studio together
with the cloud platform.
Let's Start the Configuration
To start working in Azure DevOps, let's follow the link and press "Start free with GitHub".
Give the Microsoft application access to the GitHub account data.
You'll have to create a Microsoft account to complete your registration.
After registration, create a project:
Next, we need to move to "Pipelines" - "Builds" and create a new Build pipeline.
When asked where our code is located, we will answer - GitHub.
Authorize Azure Pipelines and choose the repository with the project, for which we'll configure the static
analyzer's run.
In the template selection window, choose "Starter pipeline."
We can run static code analysis of the project in two ways: using Microsoft-hosted or self-hosted agents.
First, we'll be using Microsoft-hosted agents. Such agents are ordinary virtual machines that launch when
we run our pipeline. They are removed when the task is done. Usage of such agents allows us not to waste
time for their support and updating, but imposes certain restrictions, for example - inability to install
additional software that is used to build a project.
Let's replace the suggested default configuration for the following one for using Microsoft-hosted agents:
# Setting up run triggers
# Run only for changes in the master branch
trigger:
- master
# Since the installation of random software in virtual machines
# is prohibited, we'll use a Docker container,
# launched on a virtual machine with Windows Server 1803
pool:
vmImage: 'win1803'
container: microsoft/dotnet-framework:4.7.2-sdk-windowsservercore-1803
steps:
# Download the analyzer distribution
- task: PowerShell@2
inputs:
targetType: 'inline'
script: 'Invoke-WebRequest
-Uri https://files.viva64.com/PVS-Studio_setup.exe
-OutFile PVS-Studio_setup.exe'
- task: CmdLine@2
inputs:
workingDirectory: $(System.DefaultWorkingDirectory)
script: |
# Restore the project and download dependencies
nuget restore .ShareX.sln
# Create the directory, where files with analyzer reports will be saved
md .PVSTestResults
# Install the analyzer
PVS-Studio_setup.exe /VERYSILENT /SUPPRESSMSGBOXES
/NORESTART /COMPONENTS=Core
# Create the file with configuration and license information
"C:Program Files (x86)PVS-StudioPVS-Studio_Cmd.exe"
credentials
-u $(PVS_USERNAME)
-n $(PVS_KEY)
# Run the static analyzer and convert the report in html.
"C:Program Files (x86)PVS-StudioPVS-Studio_Cmd.exe"
-t .ShareX.sln
-o .PVSTestResultsShareX.plog
"C:Program Files (x86)PVS-StudioPlogConverter.exe"
-t html
-o .PVSTestResults
.PVSTestResultsShareX.plog
# Save analyzer reports
- task: PublishBuildArtifacts@1
inputs:
pathToPublish: PVSTestResults
artifactName: PVSTestResults
Note: according to the documentation, the container used has to be cached in the image of the virtual
machine, but at the time of writing the article it's not working and the container is downloaded every time
the task starts, which has a negative impact on the execution timing.
Let's save the pipeline and create variables which will be used for creating the license file. To do this, open
the pipeline edit window and click "Variables" in the top right corner.
Then, add two variables - PVS_USERNAME and PVS_KEY, containing the user name and license key
respectively. When creating the PVS_KEY variable don't forget to select "Keep this value secret" to encrypt
values of the variable with a 2048-bit RSA key and to suppress the output of the variable value in the task
performance log.
Save variables and run the pipeline by clicking "Run".
The second option to run the analysis - use a self-hosted agent. We can customize and manage self-hosted
agents ourselves. Such agents give more opportunities to install software, needed for building and testing
our software product.
Before using such agents, you have to configure them according to the instruction and install and configure
the static analyzer.
To run the task on a self-hosted agent, we'll replace the suggested configuration with the following:
# Setting up triggers
# Run the analysis for master-branch
trigger:
- master
# The task is run on a self-hosted agent from the pool 'MyPool'
pool: 'MyPool'
steps:
- task: CmdLine@2
inputs:
workingDirectory: $(System.DefaultWorkingDirectory)
script: |
# Restore the project and download dependencies
nuget restore .ShareX.sln
# Create the directory where files with analyzer reports will be saved
md .PVSTestResults
# Run the static analyzer and convert the report in html.
"C:Program Files (x86)PVS-StudioPVS-Studio_Cmd.exe"
-t .ShareX.sln
-o .PVSTestResultsShareX.plog
"C:Program Files (x86)PVS-StudioPlogConverter.exe"
-t html
-o .PVSTestResults
.PVSTestResultsShareX.plog
# Save analyzer reports
- task: PublishBuildArtifacts@1
inputs:
pathToPublish: PVSTestResults
artifactName: PVSTestResults
Once the task is complete, you can download the archive with analyzer reports under the "Summary" tab or
you can use the extension Send Mail that enables to configure emailing or consider another convenient tool
on Marketplace.
Analysis Results
Now let's look at some bugs found in the tested project, ShareX.
Excessive checks
To warm up, let's start with simple flaws in the code, namely, with redundant checks:
private void PbThumbnail_MouseMove(object sender, MouseEventArgs e)
{
....
IDataObject dataObject
= new DataObject(DataFormats.FileDrop,
new string[] { Task.Info.FilePath });
if (dataObject != null)
{
Program.MainForm.AllowDrop = false;
dragBoxFromMouseDown = Rectangle.Empty;
pbThumbnail.DoDragDrop(dataObject,
DragDropEffects.Copy | DragDropEffects.Move);
Program.MainForm.AllowDrop = true;
}
....
}
PVS-Studio warning: V3022 [CWE-571] Expression 'dataObject != null' is always true.
TaskThumbnailPanel.cs 415
Let's pay attention to the check of the dataObject variable for null. Why is it here? dataObject cannot be null
in this case, as it's initialized by a reference on a created object. As a result, we have an excessive check.
Critical? No. Looks succinct? No. This check is clearly better being removed so as not to clutter the code.
Let's look at another fragment of code which we can comment in a similar way:
private static Image GetDIBImage(MemoryStream ms)
{
....
try
{
....
return new Bitmap(bmp);
....
}
finally
{
if (gcHandle != IntPtr.Zero)
{
GCHandle.FromIntPtr(gcHandle).Free();
}
}
....
}
private static Image GetImageAlternative()
{
....
using (MemoryStream ms = dataObject.GetData(format) as MemoryStream)
{
if (ms != null)
{
try
{
Image img = GetDIBImage(ms);
if (img != null)
{
return img;
}
}
catch (Exception e)
{
DebugHelper.WriteException(e);
}
}
}
....
}
PVS-Studio warning: V3022 [CWE-571] Expression 'img != null' is always true. ClipboardHelpers.cs 289
In the GetImageAlternative method, the img variable is checked that it's not null right after a new instance
of the Bitmap class is created. The difference from the previous example here is that we use the
GetDIBImage method instead of the constructor to initialize the img variable. The code author suggests that
an exception might occur in this method, but he declares only blocks try and finally, omitting catch.
Therefore, if an exception occurs, the caller method GetImageAlternative won't get a reference to an object
of the Bitmap type, but will have to handle the exception in its own catch block. In this case, the img
variable won't be initialized and the execution thread won't even reach the img != null check but will get in
the catch block. Consequently, the analyzer did point to an excessive check.
Let's consider the following example of a V3022 warning:
private void btnCopyLink_Click(object sender, EventArgs e)
{
....
if (lvClipboardFormats.SelectedItems.Count == 0)
{
url = lvClipboardFormats.Items[0].SubItems[1].Text;
}
else if (lvClipboardFormats.SelectedItems.Count > 0)
{
url = lvClipboardFormats.SelectedItems[0].SubItems[1].Text;
}
....
}
PVS-Studio warning: V3022 [CWE-571] Expression 'lvClipboardFormats.SelectedItems.Count > 0' is always
true. AfterUploadForm.cs 155
Let's take a closer look at the second conditional expression. There we check the value of the read-only
Count property. This property shows the number of elements in the instance of the collection
SelectedItems. The condition is only executed if the Count property is greater than zero. It all would be fine,
but in the external if statement Count is already checked for 0. The instance of the SelectedItems collection
cannot have the number of elements less than zero, therefore, Count is either equal or greater than 0. Since
we've already performed the Count check for 0 in the first if statement and it was false, there's no point to
write another Count check for being greater than zero in the else branch.
The final example of a V3022 warning will be the following fragment of code:
private void DrawCursorGraphics(Graphics g)
{
....
int cursorOffsetX = 10, cursorOffsetY = 10, itemGap = 10, itemCount = 0;
Size totalSize = Size.Empty;
int magnifierPosition = 0;
Bitmap magnifier = null;
if (Options.ShowMagnifier)
{
if (itemCount > 0) totalSize.Height += itemGap;
....
}
....
}
PVS-Studio warning: V3022 Expression 'itemCount > 0' is always false. RegionCaptureForm.cs 1100
The analyzer noticed that the condition itemCount > 0 will always be false, as the itemCount variable is
declared and at the same time assigned zero above. This variable isn't used anywhere up to the very
condition, therefore the analyzer was right about the conditional expression, whose value is always false.
Well, let's now look at something really sapid.
The best way to understand a bug is to visualize a bug
It seems to us that a rather interesting error was found in this place:
public static void Pixelate(Bitmap bmp, int pixelSize)
{
....
float r = 0, g = 0, b = 0, a = 0;
float weightedCount = 0;
for (int y2 = y; y2 < yLimit; y2++)
{
for (int x2 = x; x2 < xLimit; x2++)
{
ColorBgra color = unsafeBitmap.GetPixel(x2, y2);
float pixelWeight = color.Alpha / 255;
r += color.Red * pixelWeight;
g += color.Green * pixelWeight;
b += color.Blue * pixelWeight;
a += color.Alpha * pixelWeight;
weightedCount += pixelWeight;
}
}
....
ColorBgra averageColor = new ColorBgra((byte)(b / weightedCount),
(byte)(g / weightedCount), (byte)(r / weightedCount),
(byte)(a / pixelCount));
....
}
I wouldn't like to show all the cards and reveal what our analyzer has found, so let's put it aside for a while.
By the name of the method, it is easy to guess what it is doing - you give it an image or a fragment of an
image, and it pixelates it. The method's code is quite long, so we won't cite it entirely, but just try to explain
its algorithm and explain what kind of a bug PVS-Studio managed to find.
This method receives two parameters: an object of the Bitmap type and the value of the int type that
indicates the size of pixelation. The operation algorithm is quite simple:
1) Divide the received image fragment into squares with the side equal to the size of pixelation. For
instance, if we have the pixelation size equal to 15, we'll get a square, containing 15x15=225 pixels.
2) Further, we traverse each pixel in this square and accumulate the values of the fields Red, Green, Blue
and Alpha in intermediate variables, and before that multiply the value of the corresponding color and the
alpha channel by the pixelWeight variable, obtained by dividing the Alpha value by 255 (the Alpha variable is
of the byte type). Also when traversing pixels we sum up the values, written in pixelWeight into the
weightedCount variable. The code fragment that executes the above actions is as follows:
ColorBgra color = unsafeBitmap.GetPixel(x2, y2);
float pixelWeight = color.Alpha / 255;
r += color.Red * pixelWeight;
g += color.Green * pixelWeight;
b += color.Blue * pixelWeight;
a += color.Alpha * pixelWeight;
weightedCount += pixelWeight;
By the way, note that if the value of the Alpha variable is zero, pixelWeight won't add to the weightedCount
variable any value for this pixel. We'll need that in the future.
3) After traversing all pixels in the current square, we can make a common "average" color for this square.
The code doing this looks as follows:
ColorBgra averageColor = new ColorBgra((byte)(b / weightedCount),
(byte)(g / weightedCount), (byte)(r / weightedCount),
(byte)(a / pixelCount));
4) Now when we got the final color and wrote it in the averageColor variable, we can again traverse each
pixel of the square and assign it a value from averageColor.
5) Go back to the point 2 while we have unhandled squares.
Once again, the weightedCount variable isn't equal to the number of all pixels in a square. For example, if an
image contains a completely transparent pixel (zero value in the alpha channel), the pixelWeight variable
will be zero for this pixel (0 / 255 = 0). Therefore, this pixel won't effect formation of the weightedCount
variable. It's quite logical - there's no point to take into account colors of a completely transparent pixel.
So it all seems reasonable - pixelation must work correctly. And it actually does. That's just not for png
images that include pixels with values in the alpha channel below 255 and unequal to zero. Notice the
pixelated picture below:
Have you seen the pixelation? Neither have we. Okay, now let's reveal this little intrigue and explain where
exactly the bug is hiding in this method. The error crept into the line of the pixelWeight variable
computation:
float pixelWeight = color.Alpha / 255;
The fact of the matter is that when declaring the pixelWeight variable as float, the code author implied that
when dividing the Alpha field by 255, he'll get fractional numbers in addition to zero and one. This is where
the problem hides, as the Alpha variable is of the byte type. When diving it by 255, we get an integer value.
Only after that it'll be implicitly cast to the float type, meaning that the fractional part gets lost.
It's easy to explain why it's impossible to pixelate png images with some transparency. Since for these pixels
values of the alpha channel are in the range 0 < Alpha < 255, the Alpha variable divided by 255 will always
result in 0. Therefore, values of the variables pixelWeight, r, g, b, a, weightedCount will also always be 0. As
a result, our averageColor will be with zero values in all channels: red - 0, blue - 0, green - 0, alpha - 0. By
painting a square in this color, we do not change the original color of the pixels, as the averageColor is
absolutely transparent. To fix this error, we just need to explicitly cast the Alpha field to the float type. Fixed
version of the code line might look like this:
float pixelWeight = (float)color.Alpha / 255;
Well, it's high time to cite the message of PVS-Studio for the incorrect code:
PVS-Studio warning: V3041 [CWE-682] The expression was implicitly cast from 'int' type to 'float' type.
Consider utilizing an explicit type cast to avoid the loss of a fractional part. An example: double A =
(double)(X) / Y;. ImageHelpers.cs 1119
For comparison, let us cite the screenshot of a truly pixelated image, obtained on the corrected application
version:
Potential NullReferenceException
public static bool AddMetadata(Image img, int id, string text)
{
....
pi.Value = bytesText;
if (pi != null)
{
img.SetPropertyItem(pi);
return true;
}
....
}
PVS-Studio warning: V3095 [CWE-476] The 'pi' object was used before it was verified against null. Check
lines: 801, 803. ImageHelpers.cs 801
This code fragment shows that the author expected that the pi variable can be null, that is why before
calling the method SetPropertyItem, the check pi != null takes place. It's strange that before this check the
property is assigned an array of bytes, because if pi is null, an exception of the NullReferenceException type
will be thrown.
A similar situation has been noticed in another place:
private static void Task_TaskCompleted(WorkerTask task)
{
....
task.KeepImage = false;
if (task != null)
{
if (task.RequestSettingUpdate)
{
Program.MainForm.UpdateCheckStates();
}
....
}
....
}
PVS-Studio warning: V3095 [CWE-476] The 'task' object was used before it was verified against null. Check
lines: 268, 270. TaskManager.cs 268
PVS-Studio found another similar error. The point is the same, so there is no great need to cite the code
fragment, the analyzer message will be enough.
PVS-Studio warning: V3095 [CWE-476] The 'Config.PhotobucketAccountInfo' object was used before it was
verified against null. Check lines: 216, 219. UploadersConfigForm.cs 216
The same return value
A suspicious code fragment was found in the EvalWindows method of the WindowsList class, which returns
true in all cases:
public class WindowsList
{
public List<IntPtr> IgnoreWindows { get; set; }
....
public WindowsList()
{
IgnoreWindows = new List<IntPtr>();
}
public WindowsList(IntPtr ignoreWindow) : this()
{
IgnoreWindows.Add(ignoreWindow);
}
....
private bool EvalWindows(IntPtr hWnd, IntPtr lParam)
{
if (IgnoreWindows.Any(window => hWnd == window))
{
return true; // <=
}
windows.Add(new WindowInfo(hWnd));
return true; // <=
}
}
PVS-Studio warning: V3009 It's odd that this method always returns one and the same value of 'true'.
WindowsList.cs 82
In seems logical that if in the list named IgnoreWindows there is a pointer with the same name as hWnd, the
method must return false.
The IgnoreWindows list can be filled either when calling the constructor WindowsList(IntPtr ignoreWindow)
or directly through accessing the property as it's public. Anyway, according to Visual Studio, at the moment
in the code this list is not filled. This is another strange place of this method.
Note. After talking to one of the ShareX developers, we found out that the EvalWindows method that
always returns true value was intentionally written like that.
Unsafe call of event handlers
protected void OnNewsLoaded()
{
if (NewsLoaded != null)
{
NewsLoaded(this, EventArgs.Empty);
}
}
PVS-Studio warning: V3083 [CWE-367] Unsafe invocation of event 'NewsLoaded', NullReferenceException is
possible. Consider assigning event to a local variable before invoking it. NewsListControl.cs 111
Here a very nasty case might occur. After checking the NewsLoaded variable for null, the method, which
handles an event, can be unsubscribed, for example, in another thread. In this case, by the time we get into
the body of the if statement, the variable NewsLoaded will already be null. A NullReferenceException might
occur when trying to call subscribers from the event NewsLoaded, which is null. It is much safer to use a
null-conditional operator and rewrite the code above as follows:
protected void OnNewsLoaded()
{
NewsLoaded?.Invoke(this, EventArgs.Empty);
}
The analyzer pointed to 68 similar fragments. We won't describe them all - they all have a similar call
pattern.
Return null from ToString
Recently I've found out from an interesting article of my colleague that Microsoft doesn't recommend
returning null from the overridden method ToString. PVS-Studio is well aware of this:
public override string ToString()
{
lock (loggerLock)
{
if (sbMessages != null && sbMessages.Length > 0)
{
return sbMessages.ToString();
}
return null;
}
}
PVS-Studio warning: V3108 It is not recommended to return 'null' from 'ToSting()' method. Logger.cs 167
Why assigned if not used?
public SeafileCheckAccInfoResponse GetAccountInfo()
{
string url = URLHelpers.FixPrefix(APIURL);
url = URLHelpers.CombineURL(APIURL, "account/info/?format=json");
....
}
PVS-Studio warning: V3008 The 'url' variable is assigned values twice successively. Perhaps this is a mistake.
Check lines: 197, 196. Seafile.cs 197
As we can see from the example, when declaring the url variable, it is assigned a value, returned from the
method FixPrefix. In the next line, we clear the obtained value even without using it anywhere. We get
something similar to dead code: it works, but doesn't effect the result. Most likely, this error is a result of a
copy-paste, as such code fragments take place in 9 more methods. As an example, we'll cite two methods
with a similar first line:
public bool CheckAuthToken()
{
string url = URLHelpers.FixPrefix(APIURL);
url = URLHelpers.CombineURL(APIURL, "auth/ping/?format=json");
....
}
....
public bool CheckAPIURL()
{
string url = URLHelpers.FixPrefix(APIURL);
url = URLHelpers.CombineURL(APIURL, "ping/?format=json");
....
}
Conclusions
As we can see, configuration complexity of automatic analyzer checks doesn't depend on a chosen CI-
system. It took us literally 15 minutes and several mouse clicks to configure checking of our project code
with a static analyzer.
In conclusion, we invite you to download and try the analyzer on your projects.

Contenu connexe

Tendances

Using Docker for Testing
Using Docker for TestingUsing Docker for Testing
Using Docker for TestingMukta Aphale
 
Enabling Cloud Native Buildpacks for Windows Containers
Enabling Cloud Native Buildpacks for Windows ContainersEnabling Cloud Native Buildpacks for Windows Containers
Enabling Cloud Native Buildpacks for Windows ContainersVMware Tanzu
 
PuppetConf 2016: Keynote: Pulling the Strings to Containerize Your Life - Sco...
PuppetConf 2016: Keynote: Pulling the Strings to Containerize Your Life - Sco...PuppetConf 2016: Keynote: Pulling the Strings to Containerize Your Life - Sco...
PuppetConf 2016: Keynote: Pulling the Strings to Containerize Your Life - Sco...Puppet
 
Javaone 2014 - Git & Docker with Jenkins
Javaone 2014 - Git & Docker with JenkinsJavaone 2014 - Git & Docker with Jenkins
Javaone 2014 - Git & Docker with JenkinsAndy Pemberton
 
2015 05-06-karsten gaebert-akademie-etrainings
2015 05-06-karsten gaebert-akademie-etrainings2015 05-06-karsten gaebert-akademie-etrainings
2015 05-06-karsten gaebert-akademie-etrainingsHaufe-Lexware GmbH & Co KG
 
Developer Experience Cloud Native - Become Efficient and Achieve Parity
Developer Experience Cloud Native - Become Efficient and Achieve ParityDeveloper Experience Cloud Native - Become Efficient and Achieve Parity
Developer Experience Cloud Native - Become Efficient and Achieve ParityMichael Hofmann
 
DockerCon SF 2015: Docker at Lyft
DockerCon SF 2015: Docker at LyftDockerCon SF 2015: Docker at Lyft
DockerCon SF 2015: Docker at LyftDocker, Inc.
 
Docker Enables DevOps
Docker Enables DevOpsDocker Enables DevOps
Docker Enables DevOpsBoyd Hemphill
 
Continuous Delivery with Jenkins
Continuous Delivery with JenkinsContinuous Delivery with Jenkins
Continuous Delivery with JenkinsJadson Santos
 
Dev opsec dockerimage_patch_n_lifecyclemanagement_2019
Dev opsec dockerimage_patch_n_lifecyclemanagement_2019Dev opsec dockerimage_patch_n_lifecyclemanagement_2019
Dev opsec dockerimage_patch_n_lifecyclemanagement_2019kanedafromparis
 
Docker Best Practices Workshop
Docker Best Practices WorkshopDocker Best Practices Workshop
Docker Best Practices WorkshopAhmed AbouZaid
 
SD DevOps Meet-up - Jenkins 2.0 and Pipeline-as-Code
SD DevOps Meet-up - Jenkins 2.0 and Pipeline-as-CodeSD DevOps Meet-up - Jenkins 2.0 and Pipeline-as-Code
SD DevOps Meet-up - Jenkins 2.0 and Pipeline-as-CodeBrian Dawson
 
Exploring the GitHub Service Universe
Exploring the GitHub Service UniverseExploring the GitHub Service Universe
Exploring the GitHub Service UniverseBjörn Kimminich
 
Portable infrastructure with puppet
Portable infrastructure with puppetPortable infrastructure with puppet
Portable infrastructure with puppetlkanies
 
Git and GitHub for Documentation
Git and GitHub for DocumentationGit and GitHub for Documentation
Git and GitHub for DocumentationAnne Gentle
 
Analyze This! CloudBees Jenkins Cluster Operations and Analytics
Analyze This! CloudBees Jenkins Cluster Operations and AnalyticsAnalyze This! CloudBees Jenkins Cluster Operations and Analytics
Analyze This! CloudBees Jenkins Cluster Operations and AnalyticsCloudBees
 
Cloud Foundry Summit 2015: Managing Multiple Cloud with a Single BOSH Deploym...
Cloud Foundry Summit 2015: Managing Multiple Cloud with a Single BOSH Deploym...Cloud Foundry Summit 2015: Managing Multiple Cloud with a Single BOSH Deploym...
Cloud Foundry Summit 2015: Managing Multiple Cloud with a Single BOSH Deploym...VMware Tanzu
 
DevOps@Morpho for ParisDevOps - 2nd of December 2014
DevOps@Morpho for ParisDevOps - 2nd of December 2014DevOps@Morpho for ParisDevOps - 2nd of December 2014
DevOps@Morpho for ParisDevOps - 2nd of December 2014Jean-Charles JOREL
 
Infrastructure as Code with Ansible
Infrastructure as Code with AnsibleInfrastructure as Code with Ansible
Infrastructure as Code with AnsibleDaniel Bezerra
 

Tendances (20)

Using Docker for Testing
Using Docker for TestingUsing Docker for Testing
Using Docker for Testing
 
Enabling Cloud Native Buildpacks for Windows Containers
Enabling Cloud Native Buildpacks for Windows ContainersEnabling Cloud Native Buildpacks for Windows Containers
Enabling Cloud Native Buildpacks for Windows Containers
 
PuppetConf 2016: Keynote: Pulling the Strings to Containerize Your Life - Sco...
PuppetConf 2016: Keynote: Pulling the Strings to Containerize Your Life - Sco...PuppetConf 2016: Keynote: Pulling the Strings to Containerize Your Life - Sco...
PuppetConf 2016: Keynote: Pulling the Strings to Containerize Your Life - Sco...
 
Javaone 2014 - Git & Docker with Jenkins
Javaone 2014 - Git & Docker with JenkinsJavaone 2014 - Git & Docker with Jenkins
Javaone 2014 - Git & Docker with Jenkins
 
2015 05-06-karsten gaebert-akademie-etrainings
2015 05-06-karsten gaebert-akademie-etrainings2015 05-06-karsten gaebert-akademie-etrainings
2015 05-06-karsten gaebert-akademie-etrainings
 
Developer Experience Cloud Native - Become Efficient and Achieve Parity
Developer Experience Cloud Native - Become Efficient and Achieve ParityDeveloper Experience Cloud Native - Become Efficient and Achieve Parity
Developer Experience Cloud Native - Become Efficient and Achieve Parity
 
DockerCon SF 2015: Docker at Lyft
DockerCon SF 2015: Docker at LyftDockerCon SF 2015: Docker at Lyft
DockerCon SF 2015: Docker at Lyft
 
Docker Enables DevOps
Docker Enables DevOpsDocker Enables DevOps
Docker Enables DevOps
 
Continuous Delivery with Jenkins
Continuous Delivery with JenkinsContinuous Delivery with Jenkins
Continuous Delivery with Jenkins
 
Dev opsec dockerimage_patch_n_lifecyclemanagement_2019
Dev opsec dockerimage_patch_n_lifecyclemanagement_2019Dev opsec dockerimage_patch_n_lifecyclemanagement_2019
Dev opsec dockerimage_patch_n_lifecyclemanagement_2019
 
Docker Best Practices Workshop
Docker Best Practices WorkshopDocker Best Practices Workshop
Docker Best Practices Workshop
 
SD DevOps Meet-up - Jenkins 2.0 and Pipeline-as-Code
SD DevOps Meet-up - Jenkins 2.0 and Pipeline-as-CodeSD DevOps Meet-up - Jenkins 2.0 and Pipeline-as-Code
SD DevOps Meet-up - Jenkins 2.0 and Pipeline-as-Code
 
Azure devops
Azure devopsAzure devops
Azure devops
 
Exploring the GitHub Service Universe
Exploring the GitHub Service UniverseExploring the GitHub Service Universe
Exploring the GitHub Service Universe
 
Portable infrastructure with puppet
Portable infrastructure with puppetPortable infrastructure with puppet
Portable infrastructure with puppet
 
Git and GitHub for Documentation
Git and GitHub for DocumentationGit and GitHub for Documentation
Git and GitHub for Documentation
 
Analyze This! CloudBees Jenkins Cluster Operations and Analytics
Analyze This! CloudBees Jenkins Cluster Operations and AnalyticsAnalyze This! CloudBees Jenkins Cluster Operations and Analytics
Analyze This! CloudBees Jenkins Cluster Operations and Analytics
 
Cloud Foundry Summit 2015: Managing Multiple Cloud with a Single BOSH Deploym...
Cloud Foundry Summit 2015: Managing Multiple Cloud with a Single BOSH Deploym...Cloud Foundry Summit 2015: Managing Multiple Cloud with a Single BOSH Deploym...
Cloud Foundry Summit 2015: Managing Multiple Cloud with a Single BOSH Deploym...
 
DevOps@Morpho for ParisDevOps - 2nd of December 2014
DevOps@Morpho for ParisDevOps - 2nd of December 2014DevOps@Morpho for ParisDevOps - 2nd of December 2014
DevOps@Morpho for ParisDevOps - 2nd of December 2014
 
Infrastructure as Code with Ansible
Infrastructure as Code with AnsibleInfrastructure as Code with Ansible
Infrastructure as Code with Ansible
 

Similaire à PVS-Studio in the Clouds: Analyzing Open Source on Azure DevOps

PVS-Studio and Continuous Integration: TeamCity. Analysis of the Open RollerC...
PVS-Studio and Continuous Integration: TeamCity. Analysis of the Open RollerC...PVS-Studio and Continuous Integration: TeamCity. Analysis of the Open RollerC...
PVS-Studio and Continuous Integration: TeamCity. Analysis of the Open RollerC...Andrey Karpov
 
PVS-Studio: analyzing pull requests in Azure DevOps using self-hosted agents
PVS-Studio: analyzing pull requests in Azure DevOps using self-hosted agentsPVS-Studio: analyzing pull requests in Azure DevOps using self-hosted agents
PVS-Studio: analyzing pull requests in Azure DevOps using self-hosted agentsAndrey Karpov
 
We continue checking Microsoft projects: analysis of PowerShell
We continue checking Microsoft projects: analysis of PowerShellWe continue checking Microsoft projects: analysis of PowerShell
We continue checking Microsoft projects: analysis of PowerShellPVS-Studio
 
PVS-Studio Is Now in Chocolatey: Checking Chocolatey under Azure DevOps
PVS-Studio Is Now in Chocolatey: Checking Chocolatey under Azure DevOpsPVS-Studio Is Now in Chocolatey: Checking Chocolatey under Azure DevOps
PVS-Studio Is Now in Chocolatey: Checking Chocolatey under Azure DevOpsAndrey Karpov
 
Analysis of merge requests in GitLab using PVS-Studio for C#
Analysis of merge requests in GitLab using PVS-Studio for C#Analysis of merge requests in GitLab using PVS-Studio for C#
Analysis of merge requests in GitLab using PVS-Studio for C#Andrey Karpov
 
PVS-Studio vs Chromium. 3-rd Check
PVS-Studio vs Chromium. 3-rd CheckPVS-Studio vs Chromium. 3-rd Check
PVS-Studio vs Chromium. 3-rd CheckAndrey Karpov
 
Analysis of bugs in Orchard CMS
Analysis of bugs in Orchard CMSAnalysis of bugs in Orchard CMS
Analysis of bugs in Orchard CMSPVS-Studio
 
Analysis of commits and pull requests in Travis CI, Buddy and AppVeyor using ...
Analysis of commits and pull requests in Travis CI, Buddy and AppVeyor using ...Analysis of commits and pull requests in Travis CI, Buddy and AppVeyor using ...
Analysis of commits and pull requests in Travis CI, Buddy and AppVeyor using ...Andrey Karpov
 
Looking for Bugs in MonoDevelop
Looking for Bugs in MonoDevelopLooking for Bugs in MonoDevelop
Looking for Bugs in MonoDevelopPVS-Studio
 
3 Ways to Get Started with a React App in 2024.pdf
3 Ways to Get Started with a React App in 2024.pdf3 Ways to Get Started with a React App in 2024.pdf
3 Ways to Get Started with a React App in 2024.pdfBOSC Tech Labs
 
Static Analysis: From Getting Started to Integration
Static Analysis: From Getting Started to IntegrationStatic Analysis: From Getting Started to Integration
Static Analysis: From Getting Started to IntegrationAndrey Karpov
 
Diving into VS 2015 Day2
Diving into VS 2015 Day2Diving into VS 2015 Day2
Diving into VS 2015 Day2Akhil Mittal
 
Continuous Integration using Cruise Control
Continuous Integration using Cruise ControlContinuous Integration using Cruise Control
Continuous Integration using Cruise Controlelliando dias
 
Trying to Sell PVS-Studio to Google, or New Bugs in Chromium
Trying to Sell PVS-Studio to Google, or New Bugs in ChromiumTrying to Sell PVS-Studio to Google, or New Bugs in Chromium
Trying to Sell PVS-Studio to Google, or New Bugs in ChromiumAndrey Karpov
 
Linux version of PVS-Studio couldn't help checking CodeLite
Linux version of PVS-Studio couldn't help checking CodeLiteLinux version of PVS-Studio couldn't help checking CodeLite
Linux version of PVS-Studio couldn't help checking CodeLitePVS-Studio
 
Analysis of PascalABC.NET using SonarQube plugins: SonarC# and PVS-Studio
Analysis of PascalABC.NET using SonarQube plugins: SonarC# and PVS-StudioAnalysis of PascalABC.NET using SonarQube plugins: SonarC# and PVS-Studio
Analysis of PascalABC.NET using SonarQube plugins: SonarC# and PVS-StudioPVS-Studio
 
PVS-Studio in the Clouds: Travis CI
PVS-Studio in the Clouds: Travis CIPVS-Studio in the Clouds: Travis CI
PVS-Studio in the Clouds: Travis CIAndrey Karpov
 
Why Windows 8 drivers are buggy
Why Windows 8 drivers are buggyWhy Windows 8 drivers are buggy
Why Windows 8 drivers are buggyPVS-Studio
 
PVS-Studio for Visual C++
PVS-Studio for Visual C++PVS-Studio for Visual C++
PVS-Studio for Visual C++Andrey Karpov
 
How to Improve Visual C++ 2017 Libraries Using PVS-Studio
How to Improve Visual C++ 2017 Libraries Using PVS-StudioHow to Improve Visual C++ 2017 Libraries Using PVS-Studio
How to Improve Visual C++ 2017 Libraries Using PVS-StudioPVS-Studio
 

Similaire à PVS-Studio in the Clouds: Analyzing Open Source on Azure DevOps (20)

PVS-Studio and Continuous Integration: TeamCity. Analysis of the Open RollerC...
PVS-Studio and Continuous Integration: TeamCity. Analysis of the Open RollerC...PVS-Studio and Continuous Integration: TeamCity. Analysis of the Open RollerC...
PVS-Studio and Continuous Integration: TeamCity. Analysis of the Open RollerC...
 
PVS-Studio: analyzing pull requests in Azure DevOps using self-hosted agents
PVS-Studio: analyzing pull requests in Azure DevOps using self-hosted agentsPVS-Studio: analyzing pull requests in Azure DevOps using self-hosted agents
PVS-Studio: analyzing pull requests in Azure DevOps using self-hosted agents
 
We continue checking Microsoft projects: analysis of PowerShell
We continue checking Microsoft projects: analysis of PowerShellWe continue checking Microsoft projects: analysis of PowerShell
We continue checking Microsoft projects: analysis of PowerShell
 
PVS-Studio Is Now in Chocolatey: Checking Chocolatey under Azure DevOps
PVS-Studio Is Now in Chocolatey: Checking Chocolatey under Azure DevOpsPVS-Studio Is Now in Chocolatey: Checking Chocolatey under Azure DevOps
PVS-Studio Is Now in Chocolatey: Checking Chocolatey under Azure DevOps
 
Analysis of merge requests in GitLab using PVS-Studio for C#
Analysis of merge requests in GitLab using PVS-Studio for C#Analysis of merge requests in GitLab using PVS-Studio for C#
Analysis of merge requests in GitLab using PVS-Studio for C#
 
PVS-Studio vs Chromium. 3-rd Check
PVS-Studio vs Chromium. 3-rd CheckPVS-Studio vs Chromium. 3-rd Check
PVS-Studio vs Chromium. 3-rd Check
 
Analysis of bugs in Orchard CMS
Analysis of bugs in Orchard CMSAnalysis of bugs in Orchard CMS
Analysis of bugs in Orchard CMS
 
Analysis of commits and pull requests in Travis CI, Buddy and AppVeyor using ...
Analysis of commits and pull requests in Travis CI, Buddy and AppVeyor using ...Analysis of commits and pull requests in Travis CI, Buddy and AppVeyor using ...
Analysis of commits and pull requests in Travis CI, Buddy and AppVeyor using ...
 
Looking for Bugs in MonoDevelop
Looking for Bugs in MonoDevelopLooking for Bugs in MonoDevelop
Looking for Bugs in MonoDevelop
 
3 Ways to Get Started with a React App in 2024.pdf
3 Ways to Get Started with a React App in 2024.pdf3 Ways to Get Started with a React App in 2024.pdf
3 Ways to Get Started with a React App in 2024.pdf
 
Static Analysis: From Getting Started to Integration
Static Analysis: From Getting Started to IntegrationStatic Analysis: From Getting Started to Integration
Static Analysis: From Getting Started to Integration
 
Diving into VS 2015 Day2
Diving into VS 2015 Day2Diving into VS 2015 Day2
Diving into VS 2015 Day2
 
Continuous Integration using Cruise Control
Continuous Integration using Cruise ControlContinuous Integration using Cruise Control
Continuous Integration using Cruise Control
 
Trying to Sell PVS-Studio to Google, or New Bugs in Chromium
Trying to Sell PVS-Studio to Google, or New Bugs in ChromiumTrying to Sell PVS-Studio to Google, or New Bugs in Chromium
Trying to Sell PVS-Studio to Google, or New Bugs in Chromium
 
Linux version of PVS-Studio couldn't help checking CodeLite
Linux version of PVS-Studio couldn't help checking CodeLiteLinux version of PVS-Studio couldn't help checking CodeLite
Linux version of PVS-Studio couldn't help checking CodeLite
 
Analysis of PascalABC.NET using SonarQube plugins: SonarC# and PVS-Studio
Analysis of PascalABC.NET using SonarQube plugins: SonarC# and PVS-StudioAnalysis of PascalABC.NET using SonarQube plugins: SonarC# and PVS-Studio
Analysis of PascalABC.NET using SonarQube plugins: SonarC# and PVS-Studio
 
PVS-Studio in the Clouds: Travis CI
PVS-Studio in the Clouds: Travis CIPVS-Studio in the Clouds: Travis CI
PVS-Studio in the Clouds: Travis CI
 
Why Windows 8 drivers are buggy
Why Windows 8 drivers are buggyWhy Windows 8 drivers are buggy
Why Windows 8 drivers are buggy
 
PVS-Studio for Visual C++
PVS-Studio for Visual C++PVS-Studio for Visual C++
PVS-Studio for Visual C++
 
How to Improve Visual C++ 2017 Libraries Using PVS-Studio
How to Improve Visual C++ 2017 Libraries Using PVS-StudioHow to Improve Visual C++ 2017 Libraries Using PVS-Studio
How to Improve Visual C++ 2017 Libraries Using PVS-Studio
 

Plus de Andrey Karpov

60 антипаттернов для С++ программиста
60 антипаттернов для С++ программиста60 антипаттернов для С++ программиста
60 антипаттернов для С++ программистаAndrey Karpov
 
60 terrible tips for a C++ developer
60 terrible tips for a C++ developer60 terrible tips for a C++ developer
60 terrible tips for a C++ developerAndrey Karpov
 
Ошибки, которые сложно заметить на code review, но которые находятся статичес...
Ошибки, которые сложно заметить на code review, но которые находятся статичес...Ошибки, которые сложно заметить на code review, но которые находятся статичес...
Ошибки, которые сложно заметить на code review, но которые находятся статичес...Andrey Karpov
 
PVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error ExamplesPVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error ExamplesAndrey Karpov
 
PVS-Studio in 2021 - Feature Overview
PVS-Studio in 2021 - Feature OverviewPVS-Studio in 2021 - Feature Overview
PVS-Studio in 2021 - Feature OverviewAndrey Karpov
 
PVS-Studio в 2021 - Примеры ошибок
PVS-Studio в 2021 - Примеры ошибокPVS-Studio в 2021 - Примеры ошибок
PVS-Studio в 2021 - Примеры ошибокAndrey Karpov
 
Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...
Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...
Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...Andrey Karpov
 
Best Bugs from Games: Fellow Programmers' Mistakes
Best Bugs from Games: Fellow Programmers' MistakesBest Bugs from Games: Fellow Programmers' Mistakes
Best Bugs from Games: Fellow Programmers' MistakesAndrey Karpov
 
Does static analysis need machine learning?
Does static analysis need machine learning?Does static analysis need machine learning?
Does static analysis need machine learning?Andrey Karpov
 
Typical errors in code on the example of C++, C#, and Java
Typical errors in code on the example of C++, C#, and JavaTypical errors in code on the example of C++, C#, and Java
Typical errors in code on the example of C++, C#, and JavaAndrey Karpov
 
How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)
How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)
How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)Andrey Karpov
 
Game Engine Code Quality: Is Everything Really That Bad?
Game Engine Code Quality: Is Everything Really That Bad?Game Engine Code Quality: Is Everything Really That Bad?
Game Engine Code Quality: Is Everything Really That Bad?Andrey Karpov
 
C++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical ReviewerC++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical ReviewerAndrey Karpov
 
The Use of Static Code Analysis When Teaching or Developing Open-Source Software
The Use of Static Code Analysis When Teaching or Developing Open-Source SoftwareThe Use of Static Code Analysis When Teaching or Developing Open-Source Software
The Use of Static Code Analysis When Teaching or Developing Open-Source SoftwareAndrey Karpov
 
Static Code Analysis for Projects, Built on Unreal Engine
Static Code Analysis for Projects, Built on Unreal EngineStatic Code Analysis for Projects, Built on Unreal Engine
Static Code Analysis for Projects, Built on Unreal EngineAndrey Karpov
 
Safety on the Max: How to Write Reliable C/C++ Code for Embedded Systems
Safety on the Max: How to Write Reliable C/C++ Code for Embedded SystemsSafety on the Max: How to Write Reliable C/C++ Code for Embedded Systems
Safety on the Max: How to Write Reliable C/C++ Code for Embedded SystemsAndrey Karpov
 
The Great and Mighty C++
The Great and Mighty C++The Great and Mighty C++
The Great and Mighty C++Andrey Karpov
 
Static code analysis: what? how? why?
Static code analysis: what? how? why?Static code analysis: what? how? why?
Static code analysis: what? how? why?Andrey Karpov
 
Zero, one, two, Freddy's coming for you
Zero, one, two, Freddy's coming for youZero, one, two, Freddy's coming for you
Zero, one, two, Freddy's coming for youAndrey Karpov
 

Plus de Andrey Karpov (20)

60 антипаттернов для С++ программиста
60 антипаттернов для С++ программиста60 антипаттернов для С++ программиста
60 антипаттернов для С++ программиста
 
60 terrible tips for a C++ developer
60 terrible tips for a C++ developer60 terrible tips for a C++ developer
60 terrible tips for a C++ developer
 
Ошибки, которые сложно заметить на code review, но которые находятся статичес...
Ошибки, которые сложно заметить на code review, но которые находятся статичес...Ошибки, которые сложно заметить на code review, но которые находятся статичес...
Ошибки, которые сложно заметить на code review, но которые находятся статичес...
 
PVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error ExamplesPVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error Examples
 
PVS-Studio in 2021 - Feature Overview
PVS-Studio in 2021 - Feature OverviewPVS-Studio in 2021 - Feature Overview
PVS-Studio in 2021 - Feature Overview
 
PVS-Studio в 2021 - Примеры ошибок
PVS-Studio в 2021 - Примеры ошибокPVS-Studio в 2021 - Примеры ошибок
PVS-Studio в 2021 - Примеры ошибок
 
PVS-Studio в 2021
PVS-Studio в 2021PVS-Studio в 2021
PVS-Studio в 2021
 
Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...
Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...
Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...
 
Best Bugs from Games: Fellow Programmers' Mistakes
Best Bugs from Games: Fellow Programmers' MistakesBest Bugs from Games: Fellow Programmers' Mistakes
Best Bugs from Games: Fellow Programmers' Mistakes
 
Does static analysis need machine learning?
Does static analysis need machine learning?Does static analysis need machine learning?
Does static analysis need machine learning?
 
Typical errors in code on the example of C++, C#, and Java
Typical errors in code on the example of C++, C#, and JavaTypical errors in code on the example of C++, C#, and Java
Typical errors in code on the example of C++, C#, and Java
 
How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)
How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)
How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)
 
Game Engine Code Quality: Is Everything Really That Bad?
Game Engine Code Quality: Is Everything Really That Bad?Game Engine Code Quality: Is Everything Really That Bad?
Game Engine Code Quality: Is Everything Really That Bad?
 
C++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical ReviewerC++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical Reviewer
 
The Use of Static Code Analysis When Teaching or Developing Open-Source Software
The Use of Static Code Analysis When Teaching or Developing Open-Source SoftwareThe Use of Static Code Analysis When Teaching or Developing Open-Source Software
The Use of Static Code Analysis When Teaching or Developing Open-Source Software
 
Static Code Analysis for Projects, Built on Unreal Engine
Static Code Analysis for Projects, Built on Unreal EngineStatic Code Analysis for Projects, Built on Unreal Engine
Static Code Analysis for Projects, Built on Unreal Engine
 
Safety on the Max: How to Write Reliable C/C++ Code for Embedded Systems
Safety on the Max: How to Write Reliable C/C++ Code for Embedded SystemsSafety on the Max: How to Write Reliable C/C++ Code for Embedded Systems
Safety on the Max: How to Write Reliable C/C++ Code for Embedded Systems
 
The Great and Mighty C++
The Great and Mighty C++The Great and Mighty C++
The Great and Mighty C++
 
Static code analysis: what? how? why?
Static code analysis: what? how? why?Static code analysis: what? how? why?
Static code analysis: what? how? why?
 
Zero, one, two, Freddy's coming for you
Zero, one, two, Freddy's coming for youZero, one, two, Freddy's coming for you
Zero, one, two, Freddy's coming for you
 

Dernier

CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceCALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceanilsa9823
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsJhone kinadey
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...Health
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...OnePlan Solutions
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...panagenda
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AIABDERRAOUF MEHENNI
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxbodapatigopi8531
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️anilsa9823
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsAndolasoft Inc
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionSolGuruz
 

Dernier (20)

CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceCALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 

PVS-Studio in the Clouds: Analyzing Open Source on Azure DevOps

  • 1. PVS-Studio in the Clouds: Azure DevOps Author: Oleg Andreev, Ilya Gainulin Date: 13.09.2019 Tags: CSharp, DevOps This is a second article, which focuses on usage of the PVS-Studio analyzer in cloud CI-systems. This time we'll consider the platform Azure DevOps - a cloud CICD solution from Microsoft. We'll be analyzing the ShareX project. We'll need three components. The first is the PVS-Studio analyzer. The second is Azure DevOps, which we'll integrate the analyzer with. The third is the project that we'll check in order to demonstrate the abilities of PVS-Studio when working in a cloud. So let's get going. PVS-Studio is a static code analyzer for finding errors and security defects. The tool supports the analysis of C, C++ and C# code.
  • 2. Azure DevOps. The Azure DevOps platform includes such tools as Azure Pipeline, Azure Board, Azure Artifacts and others that speed up the process of creating software and improve its quality. ShareX is a free app that lets you capture and record any part of the screen. The project is written in C# and is eminently suitable to show configuration of the static analyzer launch. The project source code is available on GitHub. The output of the cloc command for the ShareX project: Language files blank comment Code C# 696 20658 24423 102565 MSBuild script 11 1 77 5859 In other words, the project is small, but quite sufficient to demonstrate the work of PVS-Studio together with the cloud platform. Let's Start the Configuration To start working in Azure DevOps, let's follow the link and press "Start free with GitHub". Give the Microsoft application access to the GitHub account data.
  • 3. You'll have to create a Microsoft account to complete your registration. After registration, create a project:
  • 4. Next, we need to move to "Pipelines" - "Builds" and create a new Build pipeline. When asked where our code is located, we will answer - GitHub.
  • 5. Authorize Azure Pipelines and choose the repository with the project, for which we'll configure the static analyzer's run. In the template selection window, choose "Starter pipeline."
  • 6. We can run static code analysis of the project in two ways: using Microsoft-hosted or self-hosted agents. First, we'll be using Microsoft-hosted agents. Such agents are ordinary virtual machines that launch when we run our pipeline. They are removed when the task is done. Usage of such agents allows us not to waste time for their support and updating, but imposes certain restrictions, for example - inability to install additional software that is used to build a project. Let's replace the suggested default configuration for the following one for using Microsoft-hosted agents: # Setting up run triggers # Run only for changes in the master branch trigger: - master # Since the installation of random software in virtual machines # is prohibited, we'll use a Docker container, # launched on a virtual machine with Windows Server 1803 pool: vmImage: 'win1803' container: microsoft/dotnet-framework:4.7.2-sdk-windowsservercore-1803 steps: # Download the analyzer distribution - task: PowerShell@2 inputs:
  • 7. targetType: 'inline' script: 'Invoke-WebRequest -Uri https://files.viva64.com/PVS-Studio_setup.exe -OutFile PVS-Studio_setup.exe' - task: CmdLine@2 inputs: workingDirectory: $(System.DefaultWorkingDirectory) script: | # Restore the project and download dependencies nuget restore .ShareX.sln # Create the directory, where files with analyzer reports will be saved md .PVSTestResults # Install the analyzer PVS-Studio_setup.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /COMPONENTS=Core # Create the file with configuration and license information "C:Program Files (x86)PVS-StudioPVS-Studio_Cmd.exe" credentials -u $(PVS_USERNAME) -n $(PVS_KEY) # Run the static analyzer and convert the report in html. "C:Program Files (x86)PVS-StudioPVS-Studio_Cmd.exe" -t .ShareX.sln -o .PVSTestResultsShareX.plog "C:Program Files (x86)PVS-StudioPlogConverter.exe" -t html -o .PVSTestResults .PVSTestResultsShareX.plog # Save analyzer reports - task: PublishBuildArtifacts@1 inputs: pathToPublish: PVSTestResults artifactName: PVSTestResults Note: according to the documentation, the container used has to be cached in the image of the virtual machine, but at the time of writing the article it's not working and the container is downloaded every time the task starts, which has a negative impact on the execution timing. Let's save the pipeline and create variables which will be used for creating the license file. To do this, open the pipeline edit window and click "Variables" in the top right corner.
  • 8. Then, add two variables - PVS_USERNAME and PVS_KEY, containing the user name and license key respectively. When creating the PVS_KEY variable don't forget to select "Keep this value secret" to encrypt values of the variable with a 2048-bit RSA key and to suppress the output of the variable value in the task performance log. Save variables and run the pipeline by clicking "Run". The second option to run the analysis - use a self-hosted agent. We can customize and manage self-hosted agents ourselves. Such agents give more opportunities to install software, needed for building and testing our software product. Before using such agents, you have to configure them according to the instruction and install and configure the static analyzer. To run the task on a self-hosted agent, we'll replace the suggested configuration with the following: # Setting up triggers # Run the analysis for master-branch
  • 9. trigger: - master # The task is run on a self-hosted agent from the pool 'MyPool' pool: 'MyPool' steps: - task: CmdLine@2 inputs: workingDirectory: $(System.DefaultWorkingDirectory) script: | # Restore the project and download dependencies nuget restore .ShareX.sln # Create the directory where files with analyzer reports will be saved md .PVSTestResults # Run the static analyzer and convert the report in html. "C:Program Files (x86)PVS-StudioPVS-Studio_Cmd.exe" -t .ShareX.sln -o .PVSTestResultsShareX.plog "C:Program Files (x86)PVS-StudioPlogConverter.exe" -t html -o .PVSTestResults .PVSTestResultsShareX.plog # Save analyzer reports - task: PublishBuildArtifacts@1 inputs: pathToPublish: PVSTestResults artifactName: PVSTestResults Once the task is complete, you can download the archive with analyzer reports under the "Summary" tab or you can use the extension Send Mail that enables to configure emailing or consider another convenient tool on Marketplace.
  • 10. Analysis Results Now let's look at some bugs found in the tested project, ShareX. Excessive checks To warm up, let's start with simple flaws in the code, namely, with redundant checks: private void PbThumbnail_MouseMove(object sender, MouseEventArgs e) { .... IDataObject dataObject = new DataObject(DataFormats.FileDrop, new string[] { Task.Info.FilePath }); if (dataObject != null) { Program.MainForm.AllowDrop = false; dragBoxFromMouseDown = Rectangle.Empty; pbThumbnail.DoDragDrop(dataObject, DragDropEffects.Copy | DragDropEffects.Move); Program.MainForm.AllowDrop = true; } .... }
  • 11. PVS-Studio warning: V3022 [CWE-571] Expression 'dataObject != null' is always true. TaskThumbnailPanel.cs 415 Let's pay attention to the check of the dataObject variable for null. Why is it here? dataObject cannot be null in this case, as it's initialized by a reference on a created object. As a result, we have an excessive check. Critical? No. Looks succinct? No. This check is clearly better being removed so as not to clutter the code. Let's look at another fragment of code which we can comment in a similar way: private static Image GetDIBImage(MemoryStream ms) { .... try { .... return new Bitmap(bmp); .... } finally { if (gcHandle != IntPtr.Zero) { GCHandle.FromIntPtr(gcHandle).Free(); } } .... } private static Image GetImageAlternative() { .... using (MemoryStream ms = dataObject.GetData(format) as MemoryStream) { if (ms != null) { try { Image img = GetDIBImage(ms); if (img != null) { return img; } } catch (Exception e) { DebugHelper.WriteException(e); } } } .... }
  • 12. PVS-Studio warning: V3022 [CWE-571] Expression 'img != null' is always true. ClipboardHelpers.cs 289 In the GetImageAlternative method, the img variable is checked that it's not null right after a new instance of the Bitmap class is created. The difference from the previous example here is that we use the GetDIBImage method instead of the constructor to initialize the img variable. The code author suggests that an exception might occur in this method, but he declares only blocks try and finally, omitting catch. Therefore, if an exception occurs, the caller method GetImageAlternative won't get a reference to an object of the Bitmap type, but will have to handle the exception in its own catch block. In this case, the img variable won't be initialized and the execution thread won't even reach the img != null check but will get in the catch block. Consequently, the analyzer did point to an excessive check. Let's consider the following example of a V3022 warning: private void btnCopyLink_Click(object sender, EventArgs e) { .... if (lvClipboardFormats.SelectedItems.Count == 0) { url = lvClipboardFormats.Items[0].SubItems[1].Text; } else if (lvClipboardFormats.SelectedItems.Count > 0) { url = lvClipboardFormats.SelectedItems[0].SubItems[1].Text; } .... } PVS-Studio warning: V3022 [CWE-571] Expression 'lvClipboardFormats.SelectedItems.Count > 0' is always true. AfterUploadForm.cs 155 Let's take a closer look at the second conditional expression. There we check the value of the read-only Count property. This property shows the number of elements in the instance of the collection SelectedItems. The condition is only executed if the Count property is greater than zero. It all would be fine, but in the external if statement Count is already checked for 0. The instance of the SelectedItems collection cannot have the number of elements less than zero, therefore, Count is either equal or greater than 0. Since we've already performed the Count check for 0 in the first if statement and it was false, there's no point to write another Count check for being greater than zero in the else branch. The final example of a V3022 warning will be the following fragment of code: private void DrawCursorGraphics(Graphics g) { .... int cursorOffsetX = 10, cursorOffsetY = 10, itemGap = 10, itemCount = 0; Size totalSize = Size.Empty; int magnifierPosition = 0; Bitmap magnifier = null; if (Options.ShowMagnifier) { if (itemCount > 0) totalSize.Height += itemGap;
  • 13. .... } .... } PVS-Studio warning: V3022 Expression 'itemCount > 0' is always false. RegionCaptureForm.cs 1100 The analyzer noticed that the condition itemCount > 0 will always be false, as the itemCount variable is declared and at the same time assigned zero above. This variable isn't used anywhere up to the very condition, therefore the analyzer was right about the conditional expression, whose value is always false. Well, let's now look at something really sapid. The best way to understand a bug is to visualize a bug It seems to us that a rather interesting error was found in this place: public static void Pixelate(Bitmap bmp, int pixelSize) { .... float r = 0, g = 0, b = 0, a = 0; float weightedCount = 0; for (int y2 = y; y2 < yLimit; y2++) { for (int x2 = x; x2 < xLimit; x2++) { ColorBgra color = unsafeBitmap.GetPixel(x2, y2); float pixelWeight = color.Alpha / 255; r += color.Red * pixelWeight; g += color.Green * pixelWeight; b += color.Blue * pixelWeight; a += color.Alpha * pixelWeight; weightedCount += pixelWeight; } } .... ColorBgra averageColor = new ColorBgra((byte)(b / weightedCount), (byte)(g / weightedCount), (byte)(r / weightedCount), (byte)(a / pixelCount)); .... } I wouldn't like to show all the cards and reveal what our analyzer has found, so let's put it aside for a while. By the name of the method, it is easy to guess what it is doing - you give it an image or a fragment of an image, and it pixelates it. The method's code is quite long, so we won't cite it entirely, but just try to explain its algorithm and explain what kind of a bug PVS-Studio managed to find.
  • 14. This method receives two parameters: an object of the Bitmap type and the value of the int type that indicates the size of pixelation. The operation algorithm is quite simple: 1) Divide the received image fragment into squares with the side equal to the size of pixelation. For instance, if we have the pixelation size equal to 15, we'll get a square, containing 15x15=225 pixels. 2) Further, we traverse each pixel in this square and accumulate the values of the fields Red, Green, Blue and Alpha in intermediate variables, and before that multiply the value of the corresponding color and the alpha channel by the pixelWeight variable, obtained by dividing the Alpha value by 255 (the Alpha variable is of the byte type). Also when traversing pixels we sum up the values, written in pixelWeight into the weightedCount variable. The code fragment that executes the above actions is as follows: ColorBgra color = unsafeBitmap.GetPixel(x2, y2); float pixelWeight = color.Alpha / 255; r += color.Red * pixelWeight; g += color.Green * pixelWeight; b += color.Blue * pixelWeight; a += color.Alpha * pixelWeight; weightedCount += pixelWeight; By the way, note that if the value of the Alpha variable is zero, pixelWeight won't add to the weightedCount variable any value for this pixel. We'll need that in the future. 3) After traversing all pixels in the current square, we can make a common "average" color for this square. The code doing this looks as follows: ColorBgra averageColor = new ColorBgra((byte)(b / weightedCount), (byte)(g / weightedCount), (byte)(r / weightedCount), (byte)(a / pixelCount)); 4) Now when we got the final color and wrote it in the averageColor variable, we can again traverse each pixel of the square and assign it a value from averageColor. 5) Go back to the point 2 while we have unhandled squares. Once again, the weightedCount variable isn't equal to the number of all pixels in a square. For example, if an image contains a completely transparent pixel (zero value in the alpha channel), the pixelWeight variable will be zero for this pixel (0 / 255 = 0). Therefore, this pixel won't effect formation of the weightedCount variable. It's quite logical - there's no point to take into account colors of a completely transparent pixel. So it all seems reasonable - pixelation must work correctly. And it actually does. That's just not for png images that include pixels with values in the alpha channel below 255 and unequal to zero. Notice the pixelated picture below:
  • 15. Have you seen the pixelation? Neither have we. Okay, now let's reveal this little intrigue and explain where exactly the bug is hiding in this method. The error crept into the line of the pixelWeight variable computation: float pixelWeight = color.Alpha / 255; The fact of the matter is that when declaring the pixelWeight variable as float, the code author implied that when dividing the Alpha field by 255, he'll get fractional numbers in addition to zero and one. This is where the problem hides, as the Alpha variable is of the byte type. When diving it by 255, we get an integer value. Only after that it'll be implicitly cast to the float type, meaning that the fractional part gets lost. It's easy to explain why it's impossible to pixelate png images with some transparency. Since for these pixels values of the alpha channel are in the range 0 < Alpha < 255, the Alpha variable divided by 255 will always result in 0. Therefore, values of the variables pixelWeight, r, g, b, a, weightedCount will also always be 0. As a result, our averageColor will be with zero values in all channels: red - 0, blue - 0, green - 0, alpha - 0. By painting a square in this color, we do not change the original color of the pixels, as the averageColor is absolutely transparent. To fix this error, we just need to explicitly cast the Alpha field to the float type. Fixed version of the code line might look like this: float pixelWeight = (float)color.Alpha / 255; Well, it's high time to cite the message of PVS-Studio for the incorrect code: PVS-Studio warning: V3041 [CWE-682] The expression was implicitly cast from 'int' type to 'float' type. Consider utilizing an explicit type cast to avoid the loss of a fractional part. An example: double A = (double)(X) / Y;. ImageHelpers.cs 1119 For comparison, let us cite the screenshot of a truly pixelated image, obtained on the corrected application version:
  • 16. Potential NullReferenceException public static bool AddMetadata(Image img, int id, string text) { .... pi.Value = bytesText; if (pi != null) { img.SetPropertyItem(pi); return true; } .... } PVS-Studio warning: V3095 [CWE-476] The 'pi' object was used before it was verified against null. Check lines: 801, 803. ImageHelpers.cs 801 This code fragment shows that the author expected that the pi variable can be null, that is why before calling the method SetPropertyItem, the check pi != null takes place. It's strange that before this check the property is assigned an array of bytes, because if pi is null, an exception of the NullReferenceException type will be thrown. A similar situation has been noticed in another place: private static void Task_TaskCompleted(WorkerTask task) { .... task.KeepImage = false; if (task != null) { if (task.RequestSettingUpdate) { Program.MainForm.UpdateCheckStates();
  • 17. } .... } .... } PVS-Studio warning: V3095 [CWE-476] The 'task' object was used before it was verified against null. Check lines: 268, 270. TaskManager.cs 268 PVS-Studio found another similar error. The point is the same, so there is no great need to cite the code fragment, the analyzer message will be enough. PVS-Studio warning: V3095 [CWE-476] The 'Config.PhotobucketAccountInfo' object was used before it was verified against null. Check lines: 216, 219. UploadersConfigForm.cs 216 The same return value A suspicious code fragment was found in the EvalWindows method of the WindowsList class, which returns true in all cases: public class WindowsList { public List<IntPtr> IgnoreWindows { get; set; } .... public WindowsList() { IgnoreWindows = new List<IntPtr>(); } public WindowsList(IntPtr ignoreWindow) : this() { IgnoreWindows.Add(ignoreWindow); } .... private bool EvalWindows(IntPtr hWnd, IntPtr lParam) { if (IgnoreWindows.Any(window => hWnd == window)) { return true; // <= } windows.Add(new WindowInfo(hWnd)); return true; // <= } } PVS-Studio warning: V3009 It's odd that this method always returns one and the same value of 'true'. WindowsList.cs 82 In seems logical that if in the list named IgnoreWindows there is a pointer with the same name as hWnd, the method must return false. The IgnoreWindows list can be filled either when calling the constructor WindowsList(IntPtr ignoreWindow) or directly through accessing the property as it's public. Anyway, according to Visual Studio, at the moment in the code this list is not filled. This is another strange place of this method.
  • 18. Note. After talking to one of the ShareX developers, we found out that the EvalWindows method that always returns true value was intentionally written like that. Unsafe call of event handlers protected void OnNewsLoaded() { if (NewsLoaded != null) { NewsLoaded(this, EventArgs.Empty); } } PVS-Studio warning: V3083 [CWE-367] Unsafe invocation of event 'NewsLoaded', NullReferenceException is possible. Consider assigning event to a local variable before invoking it. NewsListControl.cs 111 Here a very nasty case might occur. After checking the NewsLoaded variable for null, the method, which handles an event, can be unsubscribed, for example, in another thread. In this case, by the time we get into the body of the if statement, the variable NewsLoaded will already be null. A NullReferenceException might occur when trying to call subscribers from the event NewsLoaded, which is null. It is much safer to use a null-conditional operator and rewrite the code above as follows: protected void OnNewsLoaded() { NewsLoaded?.Invoke(this, EventArgs.Empty); } The analyzer pointed to 68 similar fragments. We won't describe them all - they all have a similar call pattern. Return null from ToString Recently I've found out from an interesting article of my colleague that Microsoft doesn't recommend returning null from the overridden method ToString. PVS-Studio is well aware of this: public override string ToString() { lock (loggerLock) { if (sbMessages != null && sbMessages.Length > 0) { return sbMessages.ToString(); } return null; } } PVS-Studio warning: V3108 It is not recommended to return 'null' from 'ToSting()' method. Logger.cs 167 Why assigned if not used? public SeafileCheckAccInfoResponse GetAccountInfo() { string url = URLHelpers.FixPrefix(APIURL);
  • 19. url = URLHelpers.CombineURL(APIURL, "account/info/?format=json"); .... } PVS-Studio warning: V3008 The 'url' variable is assigned values twice successively. Perhaps this is a mistake. Check lines: 197, 196. Seafile.cs 197 As we can see from the example, when declaring the url variable, it is assigned a value, returned from the method FixPrefix. In the next line, we clear the obtained value even without using it anywhere. We get something similar to dead code: it works, but doesn't effect the result. Most likely, this error is a result of a copy-paste, as such code fragments take place in 9 more methods. As an example, we'll cite two methods with a similar first line: public bool CheckAuthToken() { string url = URLHelpers.FixPrefix(APIURL); url = URLHelpers.CombineURL(APIURL, "auth/ping/?format=json"); .... } .... public bool CheckAPIURL() { string url = URLHelpers.FixPrefix(APIURL); url = URLHelpers.CombineURL(APIURL, "ping/?format=json"); .... } Conclusions As we can see, configuration complexity of automatic analyzer checks doesn't depend on a chosen CI- system. It took us literally 15 minutes and several mouse clicks to configure checking of our project code with a static analyzer. In conclusion, we invite you to download and try the analyzer on your projects.