Works on Windows but not on HPUX, Help Please

S

Smurff

Hi,

This code works fine on win and linux but not on hpux. All is compiled
with gcc. Can anyone help please?

/*****************************************************************************/
/*
*/
/* encrypt
*/
/*
*/
/*****************************************************************************/
/* Description: Utility function that simply encrypts a string. Used
for */
/* simple password storage in the config file.
*/
/*
*/
/*****************************************************************************/
void encrypt(char str[],int key)
{
unsigned int i;
for(i=0;i<strlen(str);++i)
{
str = str - key;
}
}

/*****************************************************************************/
/*
*/
/* decrypt
*/
/*
*/
/*****************************************************************************/
/* Description: Utility function that simply decrypts a string. Used
for */
/* simple password storage in the config file.
*/
/*
*/
/*****************************************************************************/
void decrypt(char str[],int key)
{
unsigned int i;
for(i=0;i<strlen(str);++i)
{
str = str + key;
}
}


The decrypt function even shortens the length, which as you can see,
shouldnt happen and doesnt on other OSs

Any help would be great, thanks
Kind regards
Danny
 
W

Walter Roberson

Smurff said:
This code works fine on win and linux but not on hpux. All is compiled
with gcc. Can anyone help please?

You didn't really say what symptoms you saw.
void encrypt(char str[],int key)
{
unsigned int i;
for(i=0;i<strlen(str);++i)
{
str = str - key;
}
}

void decrypt(char str[],int key)
{
unsigned int i;
for(i=0;i<strlen(str);++i)
{
str = str + key;
}
}

The decrypt function even shortens the length, which as you can see,
shouldnt happen and doesnt on other OSs

If key happens to match any character in str[] then the subtraction
is going to produce a 0 at the corresponding position, and that is
going to have the effect of shortening the string as far as strlen()
is concerned.

But if that isn't happening for you on some systems with the same input,
then my hypothesis would be that you are encountering differences
as to whether char is signed or unsigned.
 
D

Default User

Smurff said:
Hi,

This code works fine on win and linux but not on hpux. All is compiled
with gcc. Can anyone help please?
The decrypt function even shortens the length, which as you can see,
shouldnt happen and doesnt on other OSs

Please post a COMPLETE minimal program that demonstrates the problem.
We need to see your test driver as well as the routine. What key? What
string?




Brian
 
P

pete

Walter said:
Smurff said:
This code works fine on win and linux but not on hpux.
All is compiled with gcc. Can anyone help please?

You didn't really say what symptoms you saw.
void encrypt(char str[],int key)
{
unsigned int i;
for(i=0;i<strlen(str);++i)
{
str = str - key;
}
}

void decrypt(char str[],int key)
{
unsigned int i;
for(i=0;i<strlen(str);++i)
{
str = str + key;
}
}

The decrypt function even shortens the length, which as you can see,
shouldnt happen and doesnt on other OSs

If key happens to match any character in str[] then the subtraction
is going to produce a 0 at the corresponding position, and that is
going to have the effect of shortening the string as far as strlen()
is concerned.

But if that isn't happening for you on some
systems with the same input,
then my hypothesis would be that you are encountering differences
as to whether char is signed or unsigned.


There might also be a problem with
implementation defined behavior
when char is signed and the result of the subtraction
isn't within the range of char.

If the value of key is INT_MIN,
that would cause undefined behavior in encrypt.
 
T

Tom St Denis

Smurff said:
void encrypt(char str[],int key)
{
unsigned int i;
for(i=0;i<strlen(str);++i)
{
str = str - key;
}
}


Aside from being totally weak it's also plagued by the fact the LENGTH
OF THE STRING CAN CHANGE.

What if str == key?

mmm homework.

Tom
 
S

Skarmander

Smurff said:
Hi,

This code works fine on win and linux but not on hpux. All is compiled
with gcc. Can anyone help please?

/*****************************************************************************/
/*

Box comments suck.

As we can see here. They're allergic to varying line lengths. Just /* and */
with appropriate whitespace will do.
/* encrypt
*/
/*
*/
/*****************************************************************************/
/* Description: Utility function that simply encrypts a string. Used
for */
/* simple password storage in the config file.
*/
/*
*/
/*****************************************************************************/
void encrypt(char str[],int key)
{
unsigned int i;
for(i=0;i<strlen(str);++i)

Not advisable. You're counting on your compiler to optimize the evaluation
of strlen(). In this loop it can't do that, in fact, since you're changing
the string and hence may change its length.
{
str = str - key;


Wrong in two ways:

- What if str - key == '\0'? You've just cut your string short.
- What if str - key is not representable in a char? In particular, if
char is signed, the result is implementation-defined, since you're
subtracting an int from a char, which gets you an int. You don't want that.

Here's a possible trivial encryption function:

void encrypt(unsigned char *data, size_t datalen, const unsigned char
*key, size_t keylen) {
size_t i;
for (i = 0; i != datalen; ++i) {
data ^= key[i % keylen];
}
}

This function is its own decryption function. Either call it again to
decrypt or copy the body if you don't want to expose this implementation detail.

It operates on bytes, not characters. The resulting block of data could
contain NUL characters, or in general characters you can't print. You should
use an escape mechanism to read and write the encrypted data -- for example,
writing it as a string of hexadecimal digits or using Base64 encoding.

Do not use this to hide actual secrets, the kind your company's livelihood
depends on. Breaking the encryption is trivial.

S.
 
S

Smurff

Sorry I am a muppet. I used static void and that fixed it.

Sorry to waist your time
Danny
 
K

Keith Thompson

Smurff said:
Sorry I am a muppet. I used static void and that fixed it.

Sorry to waist your time

I don't see how using static void could affect the behavior of the
code fragments you posted.

Whatever else you do, you should pay attention to the excellent advice
you got in this thread. It's quite possible that your code will
happen to work in some circumstances, but will fail at precisely the
most embarrassing possible moment.
 
W

Walter Roberson

void encrypt(char str[],int key)
{
unsigned int i;
for(i=0;i<strlen(str);++i)
{
str = str - key;
}
}

If the value of key is INT_MIN,
that would cause undefined behavior in encrypt.

Hmmm, do I read C89 correctly that the char str will be
converted to an int, not an unsigned int, even if char is unsigned,
with the exception of the case where sizeof char == sizeof int
[that being the case where the value of an unsigned char might
not fit within a signed int] ?
C89 3.2.1.1 Characters and Integers


Assuming that all values of char will fit within an int:

- if char is unsigned then its minimum value would be 0,
and if the value of key is INT_MIN then 0-INT_MIN could potentially
be INT_MAX+1 (2's complement system), but on 1's complement or
signed-magnitude then -INT_MIN is INT_MAX and no undefined behaviour
would have occured for those number systems

- if char is signed then its minimum value would be SCHAR_MIN
and that minus INT_MIN might exceed INT_MAX by abs(SCHAR_MIN)
or abs(SCHAR_MIN)+1 . But in this case, it would not just be the
key of value INT_MIN that leads to the undefined behaviour: it would
be any key between INT_MIN and INT_MIN-SCHAR_MIN that would lead
to arithmetic overflow on the subtraction.


On the other hand, once the subtraction is completed, the result
is being stored back into str which is a char. If char is
signed then if the result of the subtraction is less than SCHAR_MIN
then the result of the store operation is undefined. If char
is unsigned then the result of the store operation *is* defined
no matter what the value of the subtraction was [unless the
subtraction result was undefined as per the above.]


In summary, if char is unsigned then there is undefined behaviour
in the case of key = INT_MIN on a 2s complement system, but no
undefined behaviour for 1s complement or signed magnitude;
if char is signed then there is a fair range of values of key
that will produce arithmetic overflow, and an even larger range of
values of key that will produce problems at the assignment operation
even if there was no arithmetic overflow.
 
P

pete

Walter said:
void encrypt(char str[],int key)
{
unsigned int i;
for(i=0;i<strlen(str);++i)
{
str = str - key;
}
}

If the value of key is INT_MIN,
that would cause undefined behavior in encrypt.

Hmmm, do I read C89 correctly that the char str will be
converted to an int, not an unsigned int, even if char is unsigned,
with the exception of the case where sizeof char == sizeof int
[that being the case where the value of an unsigned char might
not fit within a signed int] ?


Yes.
unsigned short can also be promoted to signed int.
Code which attempts to increment either unsigned short
or unsigned char until roll over,
without checking first to make sure that signed int
doesn't have the same number of value bits,
is undefined.
C89 3.2.1.1 Characters and Integers

Assuming that all values of char will fit within an int:

- if char is unsigned then its minimum value would be 0,
and if the value of key is INT_MIN then 0-INT_MIN could potentially
be INT_MAX+1 (2's complement system), but on 1's complement or
signed-magnitude then -INT_MIN is INT_MAX and no undefined behaviour
would have occured for those number systems

- if char is signed then its minimum value would be SCHAR_MIN
and that minus INT_MIN might exceed INT_MAX by abs(SCHAR_MIN)
or abs(SCHAR_MIN)+1 . But in this case, it would not just be the
key of value INT_MIN that leads to the undefined behaviour: it would
be any key between INT_MIN and INT_MIN-SCHAR_MIN that would lead
to arithmetic overflow on the subtraction.

On the other hand, once the subtraction is completed, the result
is being stored back into str which is a char. If char is
signed then if the result of the subtraction is less than SCHAR_MIN
then the result of the store operation is undefined. If char
is unsigned then the result of the store operation *is* defined
no matter what the value of the subtraction was [unless the
subtraction result was undefined as per the above.]

In summary, if char is unsigned then there is undefined behaviour
in the case of key = INT_MIN on a 2s complement system, but no
undefined behaviour for 1s complement or signed magnitude;


The null terminator doesn't go through the loop in encrypt.
str always has a non zero value in encrypt;
which is a positive value if char is unsigned.
If unsigned char gets promoted to signed int, as is likely,
and if key equals INT_MIN,
then the result of the subtraction will always excede INT_MAX,
regardless of 1s complement or signed magnitude.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top