The second video of the course is about integer manipulation. The video begin with a short introduction that remember you how the integer are kept in memory when we use the C and C++ language. We'll talk about how does signed and unsigned integer are stored in memory and the integer size we can use and also the standard integer type. After that we'll discuss how we compare an integer, especially how we compare signed and unsigned integer. The third section will be about overflow or underflow when doing integer operation as addition and subtraction or multiplication and division. First, let's take a look to a 8-bit signed integer. The positive value are from one to 127 and the negative value are from minus one to minus 128. The table show how the value was encoded in the memory and the slide is to remember you how the computers store a negative value using the two complements. If you had a positive value and you want to transfer it in the same value but negative, you'll need to reverse all bits and value, after that add 1. The table will show you how to do that. The important fact to remember is that if you already have the more negative value, so in the case of 8-bit integer, if you have the value minus 128, and if you reverse the sign, you get back the same value so you still have the same value minus 128, just because the integer cannot contain the value positive 128. Because this is the first time we look at code in this learning path, we'll just talk a little bit about, I'll name the variable I use. I always use the first letter of the variable to indicate the scope of the variable. In this case, all the variable are local and whole name of this variable begin with L just to indicate that this is local variable. When we'll talk about local variable, we'll see that local variable represents some special risk having clearly indicate how our local variable is a good thing when we want to create secure code. In this code I will just show how dangerous is the most negative value as we see in the previous slide. This code L read from a sting and we can think about reading from a serial port or modem or communication link. And we will see one byte that indicate how many byte you want to send back to Data Requester. Before using the size we receive from the nodal port, we just do some validation. The first evaluation we do is if the value is negative, we use the minus operator to make it positive. And after that, we verify if the requested data size is larger than the data we can send and if yes, we just truncate the request and we write back the data to the requester. The code in read them, is dangerous just because if the requester has the maximum negative value, so in this case, minus 128. It was still the same value after the operation. After that, when we will do the comparison with the size, it will not trigger the truncate operation just because the size is smaller than the data size we can send. We will then write back a lot more data that we expect just because when we will pass the size to the fwrite, it will be converted into an unassigned value because the size is of the size underscore type datatype. This is an unsigned type. The negative value will be just converted into a very large integer positive value. If we have a eight bit unsigned integer, the minimal value is zero and the maximal value is 255. No negative value are possible with an unsigned integer. In C and C plus plus, the eight bits integer are named char, so you have the type char and the type unsigned char. The 16 bits integer are named short, and you naturally have the unsigned short too. We also have 32 bits integer, and 64 bit integer. The memory size integer type use depend on the compiler and depend on the operating system. As we saw in the previous slide, char and unsigned char usually take eight bits. It's almost always the case, except in some very rare platform as DSP, where char is not eight bits. The short and the unsigned short use 16 bit or two bytes. The int and unsigned int normally use 32 bits, but sometimes use 64 bits. In the past, we also already saw a integer that was 16 bits, but it's no more present in this day. The type long or unsigned long are sometimes 32 bits and sometimes 64 bits. The type long long and unsigned long long are 64 bits. But to be sure, the best way is to create a small program with the compiler you use and display the size of the integer type you plan to use. It's what we will do and we will do it on Linux first and after that on Windows, so we'll be able to compare the results. This is the the first time we use the Linux computer. You can access this Linux computer. This is the virtual machine that you will use to complete the project at the end of this learning path. It's a VirtualBox computer you can download and run without any problem. It run a Linux, the distribution is Ubuntu18.04, and I added the C plus plus compiler and some other tool like I described in the first video of the first course. The source I use for the course is already available on this virtual computer, so you don't have to download it. You already have it. I just start Visual Studio Code, and I open the folder named secure underscore C underscore CPP that is present in the home folder of the tinyhttp user on this computer. [inaudible] all the sample that we use in the learning path. For this first video, we'll take a look to the integer size sample, so I can open it. You see that I have a makefile that will be useful to compile the sample, and also I have the source file material. This is the source file. We'll just make it larger a little bit. A very simple program. What I do is to print the size of different type like you see. If I want to compile it, I just go in the folder of this example. I cd Integer_Size and enter the command make. I already compiled. If I want to run the program, I can simply run it like that. Note that the compiled program are put in the binary folder in the root of the repository. It's why here I enter../Binary before the name of program I want to execute. When I execute it, I get the size of different types. We're to bool, take one byte, in the char, one byte, it's on char, one byte, two byte for the char, four bytes for the integer, eight byte for the long, and eight byte for the long long. I also will print the size for the integer type, even if I already know the size for this type. But when width is one byte, and 16 is two byte and 32 is four byte and 64 is eight byte. I just had a size of the size t type that is 8 byte on this Linux that is a 64 bit edition. We will now do exactly the same time but on Windows. You don't have the virtual computer, but you can configure it yourself. I give the instruction in the first video of the first course about how to do that. You can now retrieve the code from the git repository. For now, I already had it. I open Visual Studio and have a load distribution that contain how the project we will use in this course. For this first example, we will look at integer size example. I have it here. I will just change the current startup project in order to make the integer size a current one. I can compile it just by clicking with the right button and choose the build or rebuild in the contextual menu. I choose delete, then look to the source code. Here is the source code. Make it larger a little bit. Exactly the same source code then on the next. But the make file is not used to do to completion, the Visual Studio's project is used instead. If you want to execute it, you can just press the green arrow here or press the F5 key. Start the project. It output the same thing, except that you want to see that the long on Windows is four byte rather than eight byte on Windows. Here the standard type are exactly the same size. They are why they are standard type. The size is four byte. We note that I am now compiling for X86, so the 32 bits Windows. I can change it and choose the 64 bit Windows. Comparing again, launching the program, and we have the same size. So the long event on a four bit Windows is four byte long rather than on Linux, where the long is eight byte long when we use a 64 byte edition. As we see on Linux and Windows, some integer type don't have the same size. It's more convenient to use the standard integer type. You see them here. The size of the integer is simply greater than the type, so it's easier. When I code, I still use int and unsigned int sometime just because the system bar requires the compiler to use the more efficient size for the int and for the unsigned int. Well, the size does not really matter for me, and if I'm sure that the size of a int on all platform is enough for the task, I use int and unsigned just to make sure that the compiler is able to generate efficient coding. We will now take a look to how we compare integer. Comparing signed and unsigned value is very tricky. We will look at an example. The example name is Integer_Compare and that this will help us to understand what happens when we do such comparison. On Windows, the solution is open, so we'll navigate to look at the integer compare sample. You have that code here. We'll just set the project as the startup project. Good. We'll look to the code. The code will do the texts in the 32 bits and with eight bits integer. Each test is about the same, but the size of the integer is not the same. The test in here is the value and do some comparison and display the result of the comparison. Exactly the same test, the value change for the eight byte, but the comparison are the same. We'll just start doing that exemption. Here we have the result. Yes, we get zero, it's what we were expecting. At minute one, it got zero, not expected. Minute 1, smaller or equal to zero. Here we have something very odd. Minus 1 smaller done a very being number, so where it false, we also have something we don't expect here. Does minus 1 ago equal to a very large number? False, it's expected. But minus 1 smaller or equal to a very large number and we have false again. Here, we have minus 1 equal to a very large number, in fact, the larger value will onsite hand can hold and we have a true, so where the comparison is clearly an error. Here, we have minus 1, smaller on this number and then down, so it's false. We saw here that in the eight bits, all the comparison worked very fine. If the eight bits comparison work very fine is, because there's also the compilers convert all eight bytes value in 32 bytes value before comparing. The comparison is working fine. Do that just because the compiler want to generate efficient code on Windows computer, it's more efficient to compare 32 bits ins than eight bits. So they do the conversion and this avoid all problem. This would be the same thing with the 16-bit integer. So we'll not have that problem. But if we use unsigned comparison on 32 bits, the conversion is not done. And we compare signed and unsigned value, in a way that can clearly cause error rise we can see here. When we compile the project just to have it, we get some warning here, here, and here. We saw that we saw tree warning. We saw more error than that. So yes, they can then emit warning for some cases. But in some situation, the compiler is not even able to generate a warning even if the comparison result may be wrong. Just a quick summary after the sample we saw. First, we saw that comparison between signed and unsigned integer can give the wrong answer, not really the wrong answer but not the answer we were expecting. It's particularly true with the 32 bits value when we use the Visual Studio 2019. It could be true with other compiler also. When we use eight bits, we are safe. But don't be too confident. This could not be the case with how the compiler we can find on the market. In some case the compiler will give us warning, which is very good. If they do it, we have to take it very seriously. But the worst, in some case, the compiler just don't give us warning. The best solution is simply to completely avoid a signed and unsigned comparison. So always use only signed value or only unsigned value if we need to do the comparison. If we don't follow this simple rule, just make sure before the comparison that both value are possessive in this case, make the comparison safe. So even if the two-variable are one signed and one unsigned, if you are sure that both value are positive, the comparison would work as we expect when we do integer comparison. In the next section, we'll talk about overflow and underflow when we do integer operation. Again, the simple which we'll show what happen is maybe by looking at the short example. So this is what we will do on Windows [inaudible] We now take a look to the integers. Add sub sample. This is it. As the last example we look at. We have the test using the eight bits and a 32-bit integer. That is how very simple we [inaudible] the variable. And then we do some operation in addition and subtraction. And we look to the value we get and we'll try to look if we have an issue or not. So first I will recombine the example. We saw that we don't have any warning. Even if the card is on purpose credit to cause overflow. So just [inaudible] the sample. Here we get the value so the first S is on the 8 bit unsigned. I start with zero, we add one, I add 254 and I get 255 totally expected. I add one and I get 0 so it's the overflow minus 1 and I get back to 255 so underflow and this line. First thing to notice the compiler don't give any warning and we didn't not have any execution error. Same thing with signed right now so we add 1 yes more 126 and yes we get 127 as expected. We still add 1 and we get minus 128. So here we clearly have an overflow. I deal with minus 1 and I get 127 so I clearly get another flow here and I shown here. Another flow in the negative value. Again, no execution error, no compiler warning. Same test using the 32 bits we get the exactly the same behavior. How to avoid overflow or underflow. First, the programmer have to always choose the appropriate data type, so to choose a n integer type that can fit how the value expected to have in the variable. If we need, we can also do, add test to the code so in some case it's easier to put the test before they could operation and some other cases it's easier to put the test after the comparison. So example, if we talk about unsigned value and we have a small simple addition, so A plus B. If the value resulting of the operation is smaller than A or smaller than B, you get an overflow. If we have a subtraction so or again A minus B, it's simpler to test before so if we have A smaller than B, we clearly get an underflow when executing the operation. If we use same value, the verification is a little bit more complex and it's depend the sign of the both value we addition or subtract. The table here's resume how we can do the validation. In the scale of validation are executed after the operation. Example, if we have both positive value and we do the addition, the condition is exactly as if we have unsigned value and in some case we don't add the risks because if we had shown one value that is positive and one value that is negative because of way of the data is encoded, we don't have any risks for the addition. The same thing if we have both value of the main sign and we use a subtraction we have absolutely no risk. When doing division we cannot have overflow or underflow. We can have an error condition when we divide it by 0 but this time we'll have [inaudible] error. So it's not like an overflow or an underflow. When we do multiplication we clearly can have overflow. The easy way to verify if we have overflow occurred is simply do the reverse operation so do the division and verify if the result is what we expect so we can do this test to make sure. This is the end of this video. The next video is about how to securely use locale variable in C and C Plus Plus program.