We all make mistakes so do programmers. Programming is not an easy process, and not a single program is complete without errors in the process. Some of the bugs, the most unpleasant, are logical. It is extremely difficult to search for them, and often such errors “emerge” already in the process of exploitation. Syntax errors and typos are the most innocent. In almost all languages, interpreters and compilers identify them. Something can be calculated with automatic or beta testing.
But now we have decided to talk about the most common mistakes that make almost everything. For experienced developers, this list will just refresh your memory. After all, we are all human, and the slightest inattention can lead to “dancing on the old and well-known rake.”
Dealing with undeclared variables
The essence of the error is simple. You start using a variable that was not specified in the variable declaration block and did not receive its own type. How the program will respond depends on the selected language:
- If the syntax of the LP requires a hard declaration and typing of variables, the interpreter will “fly out” from the compilation process with an error. This is a good case, as you, most likely, will quickly understand what is the matter, because an undeclared object will be present in the specified line of error.
- When using languages with a less rigid structure, the variable “appears” automatically from the moment it appears in the code. It would seem that it is convenient. In fact, debugging in the case of such an error is much more complicated. Any value can be written to your variable, including the type not provided by the program. As a result, the code will “fly out” in the line with an attempt to perform some kind of calculation or another type of processing with the participation of this variable, which will complicate the search for the problem. In the worst case, the error will be implicit, logical, i.e. The program will work, but will give an incorrect result.
Do not forget to check all variables, make sure that you declare them. And with an implicit declaration, it is desirable to use some additional possibilities for improving the style. For example, comments.
Initialization of variables without initial value
It is not enough to declare variables, it is necessary to monitor their initial values. In most languages, before you “put” something in the selected memory area, residual “garbage” will be stored there, i.e. any binary code that remained in the cells before the program started. This leads to unpleasant incidents.
Here is an example of such a code:
As a result of its execution, you can enter, for example, the numbers 2 and 5, and as a result get 2384.
If you carefully read the code, the cause of the error is obvious. The program first produces a summation of num1 and num2, and only then requests the input of their values. What was stored in the memory cells before, then the computer and folded. Move the data entry lines above the addition operation, and the problem will be solved.
This error especially often occurs when using off-the-shelf functions stored in separate files or libraries. No compiler will miss such a bug. But the search for the reasons for the constant “departure” on the line with the function often takes a lot of time. Just because the developer sees the line with an error and starts looking for the cause somewhere nearby.
It would seem that the situation is so obvious that there is nothing to talk about. But remember, how many times have you spent time trying to find a similar bug? And how long did it come to you that you forgot to register a file or library connection at the very beginning of the program? That is why this most popular mistake and takes place in our list.
Sometimes it happens that the code looks logical, and the program crashes due to problems with allocating memory for a particular type of variable.
Let’s give an example in C ++:
These lines of the program perform the addition of two variables, after which a certain amount of memory is allocated for the variable G, the value of which is stored in A. It seems that there should be no problems.
But if the values of B and C are large, their sum “does not fit” in the amount of memory that is A. As a result of this overflow, instead of the expected positive value, the variable A will be a negative number. And on the line of memory allocation for G, the program will show an error.
To avoid this is simple: do not forget to add a check of values to the maximum allowed.
Buffer overflow error was one of the most legendary in programming, since this vulnerability led to the creation of a whole series of “worm” viruses, starting with the “worm” of Morris. Some modern languages are protected from this vulnerability, and therefore as a result of overflow, the program just crashes by mistake. Others are still susceptible to such a bug, as a result, the user gets “holes” in computer protection, through which malicious code can penetrate.
The simplest example of a similar problem can be described as follows: a string variable that can hold a maximum of 255 characters is written with larger text. If the last of the characters that no longer fit into the allocated memory stack, the compiler “reads” as additional addresses of memory cells, it refers to them. And ready to write in this area of memory “excess” of information. This is used by “worms”, which are thrown into the variable “garbage information”, followed by malicious code, which the program “disciplined” places in the computer’s memory.
There are problems in the case of attempts to consider something from such a variable. Even if the vulnerability is not used by malicious code, the program, when reading, also accesses memory cells located outside the buffer, and the program starts processing additional cells. But any “junk” data, for example random information stored at specified addresses.
The usual “protection against a fool”, established for each case of receiving data from the user or from an external utility, helps to combat this phenomenon. Those. checking for compliance with the type, range of values, lack of executable code and other parameters important for the smooth operation of the program.
Errors in the estimation of the boundaries of the array
There is an opinion that such an error can be made only in C or C ++. In fact, accessing a non-existent array element is possible in Python, Java, and many other languages. The essence of the problem lies in the fact that the programmer, because of negligence or because of an error in the calculations, refers to the element of the array with a non-existent number.
The most simple example:
- You defined an array of 10 elements.
- The numbering in the array starts from zero, i.e. There are numbers from 0 to 9.
- You forget about this feature of the array and refer to the element with the index 10.
In this case, the program accesses the unused memory area, assigns this random value to the element with the index 10. The result of processing the “garbage” information is, of course, unpredictable.
To avoid problems, do not be lazy to write an additional check on the boundary values. It is better to add a couple of lines of code than to encounter unintelligible results due to a random bug.
“Forgotten” Resource Limits
This problem occurs when manually managing memory, as well as when working with databases or creating dimensionless arrays. Without strict control and restrictions, you risk getting one of two options:
- The program ignores memory cells occupied by useful information. As a result, critical errors occur.
- The application “eats” almost all of the RAM, “hangs” itself and “hangs” the system.
Be careful with array limiters, check databases for a merge, and be sure to include boundary values when directly accessing RAM.
Appeal to freed memory
The error is most popular with C-programmers, since here, after completing work with a memory block, the cells are necessarily released. But in other languages there are similar problems, for example, in the case of forced cleaning in order to save resources.
The essence of the problem lies in the fact that the program accesses the freed memory after cleaning. And, of course, does not receive the expected data.
It would seem that everyone knows about this error. And check for such a bug program is quite simple. In fact, the bug is extremely popular even among experienced developers. No wonder there are constantly news about the “freezing” of large software products due to such a failure.
SQL injection and OS commands
These two types of injections are actually hacker attacks that end up with the attacker’s access to either the databases (SQL) or root access on the user’s computer.
The causes of SQL injection are low site security. Most often, they are conducted through sending messages from users (feedback form, adding posts to the forum, contacting chat, etc.). If the security hole is not closed, the attacker sends a malicious code through these forms, and the server starts executing it. And the hacker gets access to all databases.
With the OS commands the situation is similar. If you give permission to the program to use ready-made commands of the system, you must put protection against intruders, so that the application executes only those commands that were set by the developer, but could not use anything else.
One of the “favorite” mistakes of juniors. It lies in the fact that the programmer either starts “reinventing the wheel” when trying to protect users’ personal data or other important information, or, on the contrary, uses the first found option without even checking it for vulnerabilities.
With the first case, everything is clear. Data protection is not an area where you should rely only on your rather modest capabilities. An example of the second case is the use of the SHA-1 hashing algorithm. If you use the search, you will very quickly find out that this algorithm is already outdated, many vulnerabilities have been found in it, for which more than one virus has been written. That is why it is better to use SHA-2 or SHA-3.
As you can see, in most cases, the causes of bugs and vulnerabilities are the usual inattention to details and unwillingness to once again test the code. Be careful, do not forget about your “favorite mistakes” and examples from our rating. With this approach, your code will work as intended!
This site uses Akismet to reduce spam. Learn how your comment data is processed.
Recent Posts: TechnoBlogy