Prevent user passing negative numbers to a function accepting unsigned int - c

So here's the code:
int create_mask(unsigned b, unsigned e)
{
unsigned int mask=1;
if(b<e || b<0 || e<0)
{
printf("Wrong values, starting bit can't be smaller than ending.\n");
printf("Both got to be >= 0.\n");
exit(EXIT_FAILURE);
}
while(b>0)
{
printf("%u\n", b);
mask<<=1;
if(b>e)
mask|=1;
b--;
}
return ~mask; /* negates mask for later purpose that is clearing corresponding bits */
}
Function creates mask for some bit operations, but should take two unsigned ints b and e, both non-negative. Question is how to prevent user input of negative numbers?
When function is called with (-1,0) it start the loop, and shoult exit with error.

You could just input a string, check if it contains a '-' character, and yield an error if it does. Else you convert it to an unsigned integer and proceed on. (Reading as a string then converting with strtoul() is preferred over using scanf() anyway, especially while you aren't aware of all of the quirks of scanf().)
char buf[LINE_MAX];
fgets(buf, sizeof buf, stdin);
if (strchr(buf, '-') != NULL) {
fprintf(stderr, "input must be non-negative!\n");
exit(-1);
}
unsigned int n = strtoul(buf, NULL, 0);

Edit:
you can take the long int input and then checks input is in between 0 to ending range of unsigned int .if so then assign to your variable else rise an exception to the user ,you should only give unsigned numbers as input.
long int input;
unsigned int valid_input;
scanf("%ld",&input);
if((0<= input) && (input <= 4294967295))
valid_input= (unsigned int)input ;
else
printf("Unvalid input\n");
As H2CO3 said.
reading input into string and checking for first literal if it is not minus then convert into unsigned integer would be preferable rather than the below method. because half of the part unsigned integers not covered.
you can get the input into int and then if it is non negative then proceed .if it is negative rise an exception to the user ,you should not give negative input.

Take a look at this: Stopping function implicit conversion
I was able to adapt it to your issue, and it stops the program from linking. The info in the above thread seems partially incorrect because the example compiled fine. It failed to link because there was not a template specialization defined. I'm actually a little surprised that the following worked for the int vs unsigned int.
template <class T>
void foo(const T& t);
template <>
void foo<unsigned int>(const unsigned int& t)
{
}
int main(){
foo((unsigned int) 9); // will compile and link
unsigned int value(5);
foo(value);// will compile and link
foo(9.0); // will not link
foo(-9); // will not link
return 0;
}
I think that you might be over thinking this though. Is it really a problem? Would it be better to make your id type an int to begin with? Is there a min/max id that avoids the large numbers that could be mistaken for a twos compliment? This seems like an unfortunate issue with the language that it doesn't provide any easy way to stop an implicit cast.
I tested the example with Visual Studio 2010. Additionally, I didn't have the time to write a test class so if it interests you then you'll have to adapt the example to a foo class to see if it works with a constructor of a class, or if there is another way to use templates to do this. Based on the other answers, and my experience I don't think that you are going to find an easy way to do what you want.

Related

Using unsigned int as array index could lead to buffer overflows?

I have this code in which I have to find security vulnerabilities.
win() {
printf("Congratulations!");
}
setter(unsigned int i, int v, int * a) {
a[i] = v;
}
main() {
int i, v;
int a[50];
puts("i");
scanf("%d", i);
puts("v");
scanf("%d", v);
setter(i, v, a)
}
Reading on the Internet, I've found that when a conversion from an int to an unsigned int takes place, if the int is a negative number, it will be converted into a very high unsigned int. So, probably the vulnerabilty in this code is due to this conversion which takes place when setter is called in the main function. So, an attacker could give the following input: i=-1, v=40 and he will access to a part of the memory which isn't reserved to the buffer a and so, in the setter function, the attacker will be able to overwrite important values. For example, the attacker could overwrite the return address with the address of the win function in order to execute win when setter returns. Am I right?
Summary of some comments and some additions
Firstly, the code is wrong. The arguments to scanf needs to be pointers:
scanf("%d", &i); // Note the &
if the int is a negative number, it will be converted into a very high unsigned int.
Yes, this is technically true, and it's also true that this may lead to accessing the array out of bounds. However, even if you change to unsigned, there is nothing preventing the attacker from simply typing any number, including whatever the number (unsigned) -1 will be on the particular system.
The correct way of solving this security issue is to check that the inputted number are in the range [0,49]. If you use an unsigned number, you may skip checking if it's below zero for obvious reasons. But you still need to do a range check.

How can I make alphabets entered (through scanf) interpret as integers the way it's defined in enum. Please refer program below

I am trying to make a C program for converting a given number in say base x, to base y. I chose to narrow it down upto base 20 (i.e. Base 2 to 20). When it comes to scanning a hexadecimal number (includes ABCDEF too, right?) for example, I am stuck. Please look at my program below:
/* NOTE: This program uses two step approach to convert a given number in any base (except base 10, in which case we will use only "toany()") to any other base*/
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
int inum,ibase, obase;
int todec(); //function to convert to decimal from any base
int toany(int); //function to convert from decimal to any base
int exp(int,int); //used in other function
void main()
{
int num,choice;
char strr[100];
enum{A=10,B,C,D,E,F,G,H,I,J};
here:
printf("Enter the base (RADIX) of your number: ");
scanf("%d",&ibase);
printf("Enter the number in base %d: ",ibase);
scanf("%s",strr);
printf("Enter the base in which you want the output: ");
scanf("%d",&obase);
inum=atoi(strr);
switch(obase)
{
case 10:
num=todec();
printf("Output in base 10: %d\n",num);
break;
default:
if(ibase==10)
num=toany(inum);
else
num=toany(todec());
printf("Output in base %d: %d\n",obase,num);
break;
}
printf("WANNA DO IT AGAIN? If yes, Press 1 else press 0:");
scanf("%d",&choice);
if(choice==1)
goto here;
else
exit(0);
getch();
}
int exp(int p, int q)
{
int i,result=1;
for(i=1;i<=q;i++)
{
result=result*p;
}
return(result);
}
int todec()
{
int inumarr[100],dupnum=inum,i=0,counter,decnum=0;
while(dupnum!=0)
{
inumarr[i]=dupnum%10;
dupnum/=10;
i++;
}
for(counter=0;counter<i;counter++)
{
decnum=decnum+inumarr[counter]*exp(ibase, counter);
}
return(decnum);
}
int toany(int num)
{
int outnumarr[100],i=0,q,result=0;
while(num!=0)
{
outnumarr[i]=num%obase;
num=num/obase;
i++;
}
for(q=0;q<i;q++)
{
result=result+outnumarr[q]*exp(10,q);
}
return(result);
}
Thanks for reading! Now, I know it's definitely a mess where I tried to scan as a string and then applied atoi function on a string that might contain alphabets (like "19E" in base 16...which is 414 in base 10). So, I am looking for a decent solution which will allow the user of this program to enter any number like "19E" and my program will interpret that 'E' as 14 (AS DEFINED IN MY ENUM) and also a decent way to show an output of numbers like "19E" would be great.
Disclaimer: The code I've put into this answer is untested. I'm currently on a mobile device, so even compiling it is less convenient than usual. I will strive to include enough details for you to find your way past any (possible) errors, please point them out though... On another day I'll polish this post off by adding more checks (described at the end) and explain serialisation as well as deserialisation. As it stands, however, it seems you're just asking about deserialisation, so without further adeau:
Build a lookup table of some description containing each character from your base. For characters then you can (usually) get away with using string operations. For example:
unsigned char hex_digit[] = "00112233445566778899AaBbCcDdEeFf";
If you use strchr and some pointer arithmetic you can now find the offset of a character, divide by two to reduce it to a value within 0 .. 15, or modulo by two to discriminate between lowercase and uppercase.
You can devise any base like this, with a generic loop parsing the input to facilitate larger values...
size_t to_native_uimax(char *str, unsigned char *base, uintmax_t *value) {
size_t x, base_size = strlen(str);
uintmax_t v = 0;
for (x = 0; str[x]; x++) {
unsigned char *c = strchr(base, str[x]);
if (!c) break;
v *= base_size / 2;
v += (c - base) / 2;
}
*value = v;
return x;
}
Signage is a bit trickier to handle, but because we only need to handle the sign at the start of the string we can reuse the code above.
size_t to_native_imax(unsigned char *str, unsigned char *base, intmax_t *value) {
uintmax_t v = 0;
size_t x = to_native_uimax(str + !!strchr("-+", *str), base, &v);
*value = *str == '-' ? -(intmax_t)v : v;
return x;
}
Also note that this code isn't strictly portable; if it's possible that this might be deployed to a system that has negative zeros or signals on overflow more checks should precede the (intmax_t) conversion.

MQTT callback handling

I am trying to convert a byte* parameter passed into an mqtt callback function to an int for comparison and I can't seem to get it working. Any help would be welcomed.
int fsrReading;
void callback(char* topic, byte* payload, unsigned int length) {
for (int i=0;i<length;i++) {
Serial.print((char)payload[i]); // This works well
fsrReading = int((char)payload[i]);
if (fsrReading < 0){
...
The correct way to do this depends on exactly what representation of a number is being used.
I suspect the message is a string representation of a number: "1234", which is being received as an array of ascii byte values.
If that is the case, you can rebuild a String object and convert it to an int:
int fsrReading;
void callback(char* topic, byte* payload, unsigned int length) {
String value = "";
for (int i=0;i<length;i++) {
value += (char)payload[i];
}
fsrReading = value.toInt();
...
There is an example of converting a String to an Int in the arduino tutorials here: https://www.arduino.cc/en/Tutorial/StringToIntExample
EDIT: original answer part before explanation:
Depends on compiler, compiler options etc char can be signed or unsigned, cast via (char) can work different than You expect.
Example:
payload[i] is 0x81
unsigned char -> 129, then >0
signed char -> -127, then <0
Your cast via (char) is redundant (and unstable like i said)
I don't give sample code because I don't understand Your goal. Code has contradictions.
Disclaimer: Your byte seems non standard type. I belive that is unsigned char a such type NEVER is <0 .
What is main sense of this variable? In deep, it is signed or unsigned? You can cast (unigned char) but is never<0 or (signed char) - up to You
EDIT:
after comment of asker, and interpretation from knolleary hot to interpret length (important: change of loop sense, maybe you understand author correctly) I give pure C conversion
int val = 0;
for (int i=0; i<length; i++) {
val = val*10 + payload[i]-'0';
}
// If someone know end of number is marked in different way, need implement break of `for`
fsrReading =val;
I believe my is few CPU cycles/RAM better.
EDIT2: I have read few materials from Arduino community, problem with loop concatenation into String is like in many languages: many, many small allocations (while concatenation is totally not required here). Many good Arduino programmers are critical to overuse of String. It isn't "secret knowledge", it is general rule in programming.
http://forum.arduino.cc/index.php?topic=185469.0
http://www.gammon.com.au/concat

Translate string to number

I am looking for a way to take a string and check 3 possibilities.
Digit and thus converts it to a signed int (not a long)
Is a symbolic representation previously defined at runtime, and converts it to a signed int
Neither
The "symbolic representation" will be basically like an associative array that starts at 0 elements and expands as more symbols are added. For example lets say for instance that C had associative arrays (I wish) with this peusdocode:
symbol_array['q'] = 3;
symbol_array['five'] = 5;
symbol_array['negfive'] = -5;
symbol_array['random294'] = 28;
signed int i;
string = get_from_input();
if(!(i = convert_to_int(string))) {
if(!(i = translate_from_symbol(string))) {
printf("Invalid symbol or integer\n");
exit(1);
}
}
printf("Your number: %d\n, i);
The idea being if they entered "5" it would convert it to 5 via convert_to_int, and if they entered "five" it would convert it to 5 via translate_from_symbol. As what I feel may be hardest is if they entered "random294" it wouldn't convert it to 294, but to 28. If they entered "foo" then it would exit(1).
My general questions are these: (Instead of making multiple posts)
When making convert_to_int I know I shouldn't use atoi because it doesn't fail right. Some people say to use strtol but it seems tedious to convert it back to a non-long int. The simplistic (read: shortest) way I've found is using sscanf:
int i;
if ((sscanf(string, "%d", &i)) == 1){
return i;
}
However, some people look down on that even. What is a better method if not sscanf or converting strtol?
Secondly, how can I not only return an integer but also know if it found one. For example if the user entered "0" then it would return 0, thus setting off my FALSE in my if statement. I had considered using -1 if not found but since I am returning signed int's then this also suffers from the same problem. In PHP I know for example with strpos they use === FALSE
Finally, is there any short code that emulates associate arrays and/or lets me push elements on to the array in runtime?
First, you might want to revise your syntax and set the keyword apart from the operand, i.e. "neg five" instead of "negfive". Otherwise your symbol lookup for the keywords has to consider every prefix. ("random294" might be okay if your keywords aren't allowed to have digits in them.)
Sure, sscanf tells you whether you found a decimal in the return value and writes that decimal to a separate int, which is nice, but you'll have to watch out for trailing characters by checking that the number of characters read equals the length of your string with the %n format. Otherwise, sscanf will consider 5x as legal decimal number. strtol also returns a pointer to the location after the parsed decimal number, but it relies too much on checking err for my taste.
The fact that strtol uses long integers shouldn't be an issue. If the input doesn't fit into an int, return INT_MAX or INT_MIN or issue an error.
You can also easily write a wrapper function around sscanf or strtol that suits your needs better. (I know I'd like a function that returns true on success and stores the integer via a pointer argument, sscanf style, where success means: no trailing non-digit characters.)
Finally, about the associative arrays: There is no short code, at least not in C. You'll have to implement your own hash map or use a library. As a first draft, I'd use a linear list of strings and check them one by one. This is a very naive approach, but easy to implement. I assume that you don't start out with a lot of symbols, and you're not doing a lot of checks, so speed shouldn't be an issue. (You can sort the array and use binary search to speed it up, but you'd have to re-sort after every insertion.) Once you have the logic of your program working, you can start thinking about hash maps.
Something like this should do your job:
#include <stdio.h>
#include <string.h>
struct StringToLongLookUp {
char *str;
char *num;
};
struct StringToLongLookUp table[] =
{
{ "q" , "3" },
{ "five" , "5" },
{ "negfive" , "-5" },
{ "random294", "28" }
};
int translate_from_symbol(char **str)
{
int i;
for(i = 0; i < (sizeof(table) / sizeof(struct StringToLongLookUp)); i++)
{
if(strcmp(*str, table[i].str) == 0)
{
*str = table[i].num;
return 1; // TRUE
}
}
return 0; // FALSE
}
int main()
{
char buf[100];
char *in = buf;
char *out;
int val;
scanf("%s", in);
translate_from_symbol(&in);
val = strtol(in, &out, 10);
if (in != out)
{
printf("\nValue = %d\n", val);
}
else
{
printf("\nValue Invalid\n");
}
}
Of course, you get a long, but converting that to int shouldn't be an issue as mentioned above.

How to make my Hexadecimal spit out 8 digits(including leading zeros)

So, I wrote a function converting a decimal number into a hexadecimal number by using recursion, but I can't seem to figure out how to add the prefix "0x" and leading zeros to my converted hexadecimal number. Let's say I pass the number 18 into the parameters of my function. The equivalent hexadecimal number should be 0x00000012. However, I only end up getting 12 as my hexidecimal number. The same applies when I pass in a hexidecimal number 0xFEEDDAD. I end up getting only FEEDDAD without the prefix as my answer. Can someone please help me figure this out? I've listed my code below. Also, I'm only allowed to use fputc to display my output.
const char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
void hexout (unsigned long number, FILE * stream)
{
long quotient;
long remainder;
quotient = number / 16;
remainder = number % 16;
if(quotient != 0)
hexout(quotient,stream);
fputc(digits[remainder],stream);
}
void hexout (unsigned long number, FILE * stream)
{
fprintf(stream, "0x%08lX", number);
}
If you cannot use fprintf (neither sprintf), you can use this kind of code (no recursion, but a 8-chars array on the stack):
const char digits[] = "0123456789ABCDEF";
void hexout(unsigned long number, FILE * stream)
{
unsigned long int input = number;
unsigned long int quotient;
unsigned long int remainder;
unsigned short ndigit = 0;
char result[8] = {0};
// Compute digits
do
{
quotient = input / 16;
remainder = input % 16;
result[7-ndigit] = digits[remainder];
input = quotient;
ndigit++;
}
while (ndigit < 8);
// Display result
fputc('0', stream);
fputc('x', stream);
for (ndigit = 0; ndigit < 8; ndigit++)
{
fputc(result[ndigit], stream);
}
}
Of course, this can be improved a lot...
Add digits to a string, and print out string with zero-padding using fprintf. Or just use fprintf to begin with.
Your own hexout fails for obvious reasons. You cannot 'continue' to output a number of zeroes when the value reaches 0, because you don't know how much numbers you already emitted. Also, you don't know when to prepend "0x" -- it should be before you start to emit hex digits, but how can you know you are at the start?
The logical way¹ to do this is to not use recursion, but a simple loop instead. Then again -- unsaid, but a fair bet this is a homework assignment, and in that case any number of silly constraints are possible ("write a C program without using the character '{'" comes to mind). In your case it's "you must use recursion".
You must add a counter to your recursive function; when it reaches 0, you know you have output 0x, and if it's not 0 you need to output a hex digit, irrespective if your value is 0 or not. There are a couple of ways of adding a counter to a recursive function: a global variable (which would be the easiest and utterly ugliest way, so please don't stop reading here), a static variable -- only semantically better than a global --, or a pass-by-reference argument (of which some say is a myth, but then again the end result is the same).
Which method is best for you depends on how well you can defend why you used that method.
¹ So is printf("0x%08X") an "illogical" solution? Yes. It solves the problem but without any further insights. The purpose of this assignment is not to find out the existence of printf and its parameters, it's to learn how (and why) to use recursion.

Resources