staging: speakup: replace simple_strtoul() with kstrtoint()
PATCH 1/1 staging: speakup: replace simple_strtoul() with kstrtoint()
Use the newer and nicer kstrtoint(), because simple_strtoul() is now obsolete.
--- drivers/staging/speakup/varhandlers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/staging/speakup/varhandlers.c +1 -1
@@ -324,7 +324,7 @@ char *spk_s2uchar(char *start, char *dest) {int val =0 ; - val =simple_strtoul (skip_spaces (start), &start,10 ); +kstrtoint (skip_spaces (start),10 , &val);if (*start ==',' ) start++; *dest = (u_char )val;
Signature · 1 line
2.1.0
Nope. Your patch is totally wrong (buggy). Please be more careful in the future.
regards,
dan carpenter
Quoted 6 lines · Dan Carpenter
Nope. Your patch is totally wrong (buggy). Please be more careful in the future.
regards,
dan carpenter
I saw other commits replace the obsolete simple_strtoul() this way and the documentation makes it look like it is a 1 to 1 replacement.
Sorry about this. I will investigate further to understand why this is buggy and be more careful in the future.
Thanks for the review,
Luis
Quoted 8 lines · Luis de Bethencourt
Quoted 6 lines · Dan Carpenter
Nope. Your patch is totally wrong (buggy). Please be more careful in the future.
regards,
dan carpenter
Quoted 5 lines
I saw other commits replace the obsolete
simple_strtoul()this way and the documentation makes it look like it is a 1 to 1 replacement.Sorry about this. I will investigate further to understand why this is buggy and be more careful in the future.
simple_strtoul returns unsigned long and kstrtoint gives int. documentation says to use kstrtoul.
regards
sudip
Quoted 12 lines · Sudip Mukherjee
Quoted 11 lines · Luis de Bethencourt
Quoted 6 lines · Dan Carpenter
Nope. Your patch is totally wrong (buggy). Please be more careful in the future.
regards,
dan carpenterI saw other commits replace the obsolete
simple_strtoul()this way and the documentation makes it look like it is a 1 to 1 replacement.
Quoted 7 lines
Quoted 2 lines
Sorry about this. I will investigate further to understand why this is buggy and be more careful in the future.
simple_strtoulreturns unsigned long and kstrtoint gives int. documentation says to use kstrtoul.regards
sudip
Hello again Sudip :)
simple_strtoul returns an unsigned long, but in this case this is downcasted to int val. If we use kstrtoul there would be a type warning since the function expects the reference to an unsigned long. Which is why I used the related kstrtoint.
Dan has said this is buggy. I have an idea why this might be. I am isolating the code and playing with it before submitting a second version.
Thanks for the review.
Luis
Quoted 28 lines · Luis de Bethencourt
Quoted 12 lines · Sudip Mukherjee
Quoted 11 lines · Luis de Bethencourt
Quoted 6 lines · Dan Carpenter
Nope. Your patch is totally wrong (buggy). Please be more careful in the future.
regards,
dan carpenterI saw other commits replace the obsolete
simple_strtoul()this way and the documentation makes it look like it is a 1 to 1 replacement.Quoted 7 lines
Quoted 2 lines
Sorry about this. I will investigate further to understand why this is buggy and be more careful in the future.
simple_strtoulreturns unsigned long and kstrtoint gives int. documentation says to use kstrtoul.regards
sudipHello again Sudip :)
simple_strtoulreturns an unsigned long, but in this case this is downcasted to int val. If we use kstrtoul there would be a type warning since the function expects the reference to an unsigned long. Which is why I used the related kstrtoint.
Quoted 6 lines
Dan has said this is buggy. I have an idea why this might be. I am isolating the code and playing with it before submitting a second version.
Thanks for the review.
Luis
Hi,
I've investigated the issue and found the two differences between simple_stroull() and kstrtoull().
The prototypes for reference:
unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base); int kstrtoul(const char *s, unsigned int base, unsigned long *res);
The first issue is that simple_strtoull() moves the endp pointer to right after the character where the last digit used is. [0] kstrtoull() doesn't move any pointers or tell us how many characters of the string it read.
Speakup uses this to convert a string including 3 numbers into 3 ascii codes. For example "97 98 99", to get 'a', 'b', and 'c'. It loops 3 times using this function moving the start (cp) to the endp of the previous iteration. [1]
The second issue is that kstrtoull() checks for the number to be alone in the string. [2] Where rv equals the number of characters read.
s += rv;
if (*s == '\n')
s++;
if (*s) {
return -EINVAL;
}So in our case before in speakup, after reading the first number s points to the empty character between 97 and 98 and it returns -EINVAL.
IMHO there are 3 things I could do:
- Split the initial string into 3, and use simple_strtoull()
- Implement speakup's 3 number string into 3 chars differently.
- Remain using simple_strtoull() and ignore the deprecated warnings.
What do you guys think?
I'm inclined towards the first if there is interest.
Thanks,
Luis
[0] https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/arch/x86/boot/string.c?id=b953c0d234bc72e8489d3bf51a276c5c4ec85345#n118
[1] https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/staging/speakup/kobjects.c?id=b953c0d234bc72e8489d3bf51a276c5c4ec85345#n284
[2] https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/lib/kstrtox.c?id=b953c0d234bc72e8489d3bf51a276c5c4ec85345#n91
Probably once you start writing a patch you will figure it out. :)
keymap_store() is a crap function. We have the cp1 pointer that points to the end of two back to back 3 char arrays. The name cp1 is because it is the second copy of the cp buffer which is a copy of the buf buffer. Since it is a backwards array we use cp1[-3] where normally we would say array[0] and cp1[-1] to mean the last element in the array.
We need around 6 characters in cp1, but we are only garaunteed to have
2. There is no checking.
Lots of checkpatch.pl warnings.
Just focus on cleaning up keymap_store() and hopefully at the end you can just delete spk_s2uchar().
regards,
dan carpenter