Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Somme de 2 size_t

7 réponses
Avatar
batyann811
Bonjour,

C'est sûrement une question idiote mais bon je me lance.

Admettons que je veuille concatener 2 chaînes de caractères (s1 et s2)
dans un troisième (s3). Je vais donc faire un truc du genre :

size_t len_s1, len_s2;
char * s3;

len_s1 = strlen(s1);
len_s2 = strlen(s2);

s3 = malloc( len_s1 + len_s2);

Et c'est là que commence mon problème. En effet si "len_s1" et "len_s2"
sont toutes les 2 proches de la valeur maximale que peut prendre une
variable de type "size_t" alors "len_s1 + len_s2" va provoquer un
"interger overflow" et je cours à la catastrophe...

Mon problème est donc de savoir detecter ce risque de dépassement de
façon portable ?

7 réponses

Avatar
espie
In article <48be3d77$0$868$,
batyann811 wrote:
Bonjour,

C'est sûrement une question idiote mais bon je me lance.

Admettons que je veuille concatener 2 chaînes de caractères (s1 et s2)
dans un troisième (s3). Je vais donc faire un truc du genre :

size_t len_s1, len_s2;
char * s3;

len_s1 = strlen(s1);
len_s2 = strlen(s2);

s3 = malloc( len_s1 + len_s2);

Et c'est là que commence mon problème. En effet si "len_s1" et "len_s2"
sont toutes les 2 proches de la valeur maximale que peut prendre une
variable de type "size_t" alors "len_s1 + len_s2" va provoquer un
"interger overflow" et je cours à la catastrophe...



1/ len_s1 + len_s2 + 1
2/ non, jamais d'integer overflow sur les size_t, puisque c'est un type
non signe... avec une arithmetique parfaitement definie, et modulaire.

Partant de la, c'est plutot facile de verifier si le resultat n'est pas bon:
il va forcement etre plus petit que len_s1 et len_s2 ssi il y a un probleme.

en pratique, tu as d'autres soucis: le malloc va echouer bien avant que
le resultat soit faux...

bref, ce genre de choses n'est pas tres problematique, parce que tu alloues
de la memoire qui est du meme ordre de taille que la memoire deja allouee.

Par contre, si tu fais un malloc(n * size(t)), alors la oui, le probleme se
pose, et c'est meme un classique dans le milieu de la securite, ou tout le
monde a deploye des techniques pour evier le souci...
Avatar
Jean-Marc Bourguet
batyann811 writes:

Bonjour,

C'est sûrement une question idiote mais bon je me lance.

Admettons que je veuille concatener 2 chaînes de caractères (s1 et s2) dans
un troisième (s3). Je vais donc faire un truc du genre :

size_t len_s1, len_s2;
char * s3;

len_s1 = strlen(s1);
len_s2 = strlen(s2);

s3 = malloc( len_s1 + len_s2);



s3= malloc(len_s1 + len_s2 + 1);

Il faut tenir compte du caractere final.

Et c'est là que commence mon problème. En effet si "len_s1" et "len_s2"
sont toutes les 2 proches de la valeur maximale que peut prendre une
variable de type "size_t" alors "len_s1 + len_s2" va provoquer un "interger
overflow" et je cours à la catastrophe...



Mon problème est donc de savoir detecter ce risque de dépassement de façon
portable ?



Il n'y a pas de macros definissant le maximum de size_t en C90 -- il y a
SIZE_MAX dans <stdint.h> en C99 -- mais size_t est un unsigned, donc on
sait que cette limite est (size_t)-1. Donc le test est

assert((size_t)-1 - len_s1 > len_s2);

(> plutot que >= pour tenir compte du +1 de tout a l'heure qu'on ne peut
additionner nulle part sans risque d'overflow).

A+

--
Jean-Marc
FAQ de fclc: http://www.isty-info.uvsq.fr/~rumeau/fclc
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Avatar
batyann811
Marc Espie wrote:

1/ len_s1 + len_s2 + 1



Effectivement.


Par contre, si tu fais un malloc(n * size(t)), alors la oui, le probleme se
pose, et c'est meme un classique dans le milieu de la securite, ou tout le
monde a deploye des techniques pour evier le souci...



Un petit lien vers ces techniques ? Ou des mots clé pour chercher dans
google ?
Avatar
batyann811
Jean-Marc Bourguet wrote:

s3= malloc(len_s1 + len_s2 + 1);



> Il faut tenir compte du caractere final.

Oui mais bon c'est le matin et j'ai fais ça vite fait pour l'exemple. Ca
marche comme excuses ?


Il n'y a pas de macros definissant le maximum de size_t en C90 -- il y a
SIZE_MAX dans <stdint.h> en C99 -- mais size_t est un unsigned, donc on
sait que cette limite est (size_t)-1. Donc le test est

assert((size_t)-1 - len_s1 > len_s2);

(> plutot que >= pour tenir compte du +1 de tout a l'heure qu'on ne peut
additionner nulle part sans risque d'overflow).




Merci.
Avatar
Thierry B.
--{ batyann811 a plopé ceci: }--

size_t len_s1, len_s2;
char * s3;

len_s1 = strlen(s1);
len_s2 = strlen(s2);

s3 = malloc( len_s1 + len_s2);



s3 ne pourra pas contenir le '' final.

Et c'est là que commence mon problème. En effet si "len_s1" et "len_s2"
sont toutes les 2 proches de la valeur maximale que peut prendre une
variable de type "size_t" alors "len_s1 + len_s2" va provoquer un
"interger overflow" et je cours à la catastrophe...

Mon problème est donc de savoir detecter ce risque de dépassement de
façon portable ?



Joker.

--
Ah, tu sais quand tu as hacké trop longtemps quand ton clavier se blo
Avatar
espie
In article <48be4295$0$884$,
batyann811 wrote:
Marc Espie wrote:

1/ len_s1 + len_s2 + 1



Effectivement.


Par contre, si tu fais un malloc(n * size(t)), alors la oui, le probleme se
pose, et c'est meme un classique dans le milieu de la securite, ou tout le
monde a deploye des techniques pour evier le souci...



Un petit lien vers ces techniques ? Ou des mots clé pour chercher dans
google ?



cvsweb d'openbsd, src/lib/libc/stdlib
chercher l'implementation de calloc..

En tres simple, on fait une division de SIZE_MAX/n, et on verifie que c'est
plus grand que size(t).
Avatar
batyann811
Marc Espie wrote:
En tres simple, on fait une division de SIZE_MAX/n, et on verifie que c'est
plus grand que size(t).



Merci pour toutes ces infos.