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

[débutant] comment se débarrassser des warnings ?

6 réponses
Avatar
Thomas Harding
Bonjour,
je suis novice complet en C, et j'avoue que je m'y perd beaucoup :)

le code qui suit fonctionne(tm), mais produit des avertissement à la
compilation.

accessoirement, j'aimerais comprendre pourquoi je dois ajouter 1
à la longueur dans snprintf...

Bref, j'aimerais éviter que ce code « tombe en marche »...

#### CODE

#include <Python.h>
#define SSH2_MODULE
#include "ssh2.h"
[...]
static PyObject *
SSH2_Session_getFingerprint(SSH2_SessionObj *self, PyObject *args)
{
int hashtype = LIBSSH2_HOSTKEY_HASH_MD5;
unsigned char *hash;
#define BUFSIZE 20
unsigned char *fingerprint[BUFSIZE];
int i;
size_t fingerprint_len;

if (!PyArg_ParseTuple(args, "|i:getFingerprint", &hashtype))
return NULL;

fingerprint_len = (hashtype == LIBSSH2_HOSTKEY_HASH_MD5) ? 16 : 20;

hash = libssh2_hostkey_hash(self->session, hashtype);

for(i = 0; i < fingerprint_len; i++) {
if (hash[i] == '\0') {

PyErr_SetString(SSH2_Error,
"No fingerprint available using specified
hash");
return NULL;
}

}

/*
* là, c'est le gros bricolage, parce que libssh2 me renvoie
* une chaîne de 40 caractères pour le hash MD5 et 24 pour le
* SHA1, les 40 caractères correspondant aux 16 "normaux" du
* MD5 + 20 du SHA1 + 4 de n'importnawaq...
* je ne suis pas le coupable de la libssh2 :)
* Accessoirement, rien que la page MAN 3 de ***printf
* m'a donné envie d'aspirine...
*/
snprintf(fingerprint, fingerprint_len + 1, "%*s", fingerprint_len, hash);

return PyString_FromString(fingerprint);
}

### libssh2.h

LIBSSH2_API const char *libssh2_hostkey_hash(LIBSSH2_SESSION *session,
int hash_type);

### warnings

gcc -pthread -fno-strict-aliasing -DNDEBUG -g -O2 -Wall
-Wstrict-prototypes -fPIC -I/usr/include -I/usr/local/include
-I/usr/include/python2.4 -c src/ssh2/session.c -o
build/temp.linux-i686-2.4/src/ssh2/session.o
src/ssh2/session.c: In function SSH2_Session_getFingerprint:
src/ssh2/session.c:119: warning: assignment discards qualifiers from
pointer target type
src/ssh2/session.c:129: warning: passing argument 1 of snprintf from
incompatible pointer type
src/ssh2/session.c:131: warning: passing argument 1 of
PyString_FromString from incompatible pointer type

--
Thomas Harding

6 réponses

Avatar
Xavier Roche
unsigned char *fingerprint[BUFSIZE];


unsigned char fingerprint[BUFSIZE];

(unsigned char *fingerprint[BUFSIZE], c'est un tableau de pointeurs sur
des unsigned char)

de plus BUFSIZE est insuffisant: il faut prendre en compte l'octet de
terminaison ( )
c'est aussi la raison du +1 sur snprintf

Avatar
Thomas Harding
Le 20-07-2007, Xavier Roche a écrit:
unsigned char *fingerprint[BUFSIZE];


unsigned char fingerprint[BUFSIZE];

(unsigned char *fingerprint[BUFSIZE], c'est un tableau de pointeurs sur
des unsigned char)


Merci. Le pire, c'est que j'ai laissé mon K&R au boulôt.
Il a fallu aussi que je passe de unsigned char à char tout court, la
doc de l'API de libssh2 et les headers différant...

de plus BUFSIZE est insuffisant: il faut prendre en compte l'octet de
terminaison ( )
c'est aussi la raison du +1 sur snprintf


Mhhh:

snprintf(fingerprint, fingerprint_len + 1, "%*s", fingerprint_len,
hash);

est correct, ou bien je doit aussi ajouter 1 à la longueur de chaîne
formatée ? (même si la chaîne est retournée en entier au niveau du
"%*s", d'après la doc).

--
Thomas Harding


Avatar
Pierre Maurette

[...]


PyErr_SetString(SSH2_Error,
"No fingerprint available using specified
hash");


[...]

src/ssh2/session.c:119: warning: assignment discards qualifiers from
pointer target type



En plus de la réponse de Xavier Roche: PyErr_SetString() attend un
char* en second argument, vous lui donnez un const char*, c'est à dire
un pointeur vers une zone de texte non modifiable.
Peut-on supputer une erreur de la bibliothèque Python/C API ? Je
l'ignore.
Le problème c'est que modifier en zone à lecture seule peut passer sur
votre machine et crasher sur une autre.
Vous pouvez faire:
char SSH2_ErrorString[] "No fingerprint available using specified hash";

Je le mettrais dans les globales. Mais peut-être va-t-on me corriger.
J'attends les précisions avec intérêt. Je n'ai pas de certitude sur ce
qui est correct dans ce genre de situation, assez fréquente avec
certaines bibliothèques.

--
Pierre Maurette

Avatar
Thomas Harding
Le 21-07-2007, Pierre Maurette a écrit:
PyErr_SetString(SSH2_Error,
"No fingerprint available using specified
hash");
src/ssh2/session.c:119: warning: assignment discards qualifiers from
pointer target type



En plus de la réponse de Xavier Roche: PyErr_SetString() attend un
char* en second argument, vous lui donnez un const char*, c'est à dire
un pointeur vers une zone de texte non modifiable.
Peut-on supputer une erreur de la bibliothèque Python/C API ? Je
l'ignore.


En tout cas, le laisser tel quel ne génère pas d'avertissements à la
compilation.

En fait, je reprend et tente de compléter un code existant, trouvé sur
http://www.keyphrene.com

J'ai séparé la librairie python ssh2 du reste (c'est du LGPL), ajoûté
une fonction pompeusement appelée popen (parce qu'il y avait bien un
exec, mais j'aime bien écouter après avoir parlé :), et essaie
maintenant de virer les printf tout court (sauf si on passe l'option
debug).

Vu le nombre de fois où PyErr_SetString() est utilisé, j'ai quelques
heures de loisirs devant moi...

Le problème c'est que modifier en zone à lecture seule peut passer sur
votre machine et crasher sur une autre.
Vous pouvez faire:
char SSH2_ErrorString[] > "No fingerprint available using specified hash";


Puis, je suppose:
PyErr_SetString(SSH2_ErrorString[0]);

(Je lis
http://www-ipst.u-strasbg.fr/pat/program/tpc.htm#Heading61
et je me perds un peu, là...)


Je le mettrais dans les globales. Mais peut-être va-t-on me corriger.
J'attends les précisions avec intérêt. Je n'ai pas de certitude sur ce
qui est correct dans ce genre de situation, assez fréquente avec
certaines bibliothèques.


Au moins, ce fil n'est pas une perte totale de temps pour le groupe.

--
Thomas Harding


Avatar
Thomas Harding
Le 21-07-2007, Thomas Harding a écrit :
Puis, je suppose:
PyErr_SetString(SSH2_ErrorString[0]);

(Je lis
http://www-ipst.u-strasbg.fr/pat/program/tpc.htm#Heading61
et je me perds un peu, là...)


Bon, alors (plus loin): les chaînes de caractères sont considérées comme
des tableaux. Si je fais ça, il ne devrait m'afficher que la première
lettre.

donc:
PyErr_SetString(SSH2_Error, SSH2_ErrorString);



--
Thomas Harding

Avatar
Pierre Maurette
Le 21-07-2007, Pierre Maurette a écrit:
En plus de la réponse de Xavier Roche: PyErr_SetString() attend un
char* en second argument, vous lui donnez un const char*, c'est à dire
un pointeur vers une zone de texte non modifiable.
Peut-on supputer une erreur de la bibliothèque Python/C API ? Je
l'ignore.


En tout cas, le laisser tel quel ne génère pas d'avertissements à la
compilation.


OK. J'avais été obligé de faire des hypothèses sur les numéros de
lignes des warnings. Et j'avais sauté votre remarque "Il a fallu aussi
que je passe de unsigned char à char tout court, la doc de l'API de
libssh2 et les headers différant..." qui correspondait au warning.



[...]

Puis, je suppose:
PyErr_SetString(SSH2_ErrorString[0]);


Ce serait:

PyErr_SetString(SSH2_ErrorString);
ou
PyErr_SetString(&SSH2_ErrorString[0]);

Mais le mieux serait d'oublier ma remarque :-(

Encore qu'il aurait été préférable que le prototype soit:

void PyErr_SetString (PyObject* type, const char* message);

Tel quel, vous passez à PyErr_SetString() un char* qui contient un
pointeur vers une zone non modifiable. La logique veut que
PyErr_SetString() ne modifie pas cette zone. Un prototype avec const
char* aurait affirmé cette hypothèse.

--
Pierre Maurette