diff options
Diffstat (limited to 'src/common')
-rwxr-xr-x | src/common/Makefile.am | 2 | ||||
-rw-r--r-- | src/common/ibuf.c | 173 | ||||
-rw-r--r-- | src/common/ibuf.h | 71 | ||||
-rw-r--r-- | src/common/packed.c | 2 | ||||
-rw-r--r-- | src/common/packed.h | 2 | ||||
-rw-r--r-- | src/common/utf8.c | 150 | ||||
-rw-r--r-- | src/common/utf8.h | 55 |
7 files changed, 453 insertions, 2 deletions
diff --git a/src/common/Makefile.am b/src/common/Makefile.am index 94faa59..d2f6186 100755 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -11,6 +11,7 @@ libcommon_la_SOURCES = \ endianness.h endianness.c \ environment.h environment.c \ extstr.h extstr.c \ + ibuf.h ibuf.c \ io.h io.c \ fnv1a.h fnv1a.c \ leb128.h leb128.c \ @@ -21,6 +22,7 @@ libcommon_la_SOURCES = \ shuffle.h shuffle.c \ sort.h sort.c \ sqlite.h sqlite.c \ + utf8.h utf8.c \ xdg.h xdg.c \ xml.h xml.c diff --git a/src/common/ibuf.c b/src/common/ibuf.c new file mode 100644 index 0000000..6eb04e6 --- /dev/null +++ b/src/common/ibuf.c @@ -0,0 +1,173 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ibuf.c - lecture progressive d'un tampon de données + * + * Copyright (C) 2018 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "ibuf.h" + + +#include <assert.h> +#include <string.h> + + + +/****************************************************************************** +* * +* Paramètres : ibuf = tampon de données à initialiser. [OUT] * +* * +* Description : Initialise un contenu textuel pour une lecture ultérieure. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void init_text_input_buffer(input_buffer *ibuf, const char *text) +{ + ibuf->text = text; + + ibuf->len = strlen(text); + ibuf->pos = 0; + +} + + +/****************************************************************************** +* * +* Paramètres : ibuf = tampon de données à consulter. * +* * +* Description : Compte le nombre d'octets encore non lus. * +* * +* Retour : Nombre d'octets encore disponibles pour un traitement. * +* * +* Remarques : - * +* * +******************************************************************************/ + +size_t count_input_buffer_remaining(const input_buffer *ibuf) +{ + return ibuf->len - ibuf->pos; + +} + +/****************************************************************************** +* * +* Paramètres : ibuf = tampon de données à modifier. * +* count = progression de la tête de lecture à marquer. * +* * +* Description : Avance la tête de lecture dans le tampon de données. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void advance_input_buffer(input_buffer *ibuf, size_t count) +{ + assert((ibuf->pos + count) <= ibuf->len); + + ibuf->pos += count; + +} + + +/****************************************************************************** +* * +* Paramètres : ibuf = tampon de données à consulter. * +* * +* Description : Fournit un accès brut au niveau de la tête de lecture. * +* * +* Retour : Référence au texte brut courant. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const char *get_input_buffer_text_access(const input_buffer *ibuf) +{ + return ibuf->text + ibuf->pos; + +} + + +/****************************************************************************** +* * +* Paramètres : ibuf = tampon de données à parcourir. * +* * +* Description : Fournit et avance la tête de lecture courante. * +* * +* Retour : Caractère courant. * +* * +* Remarques : - * +* * +******************************************************************************/ + +char text_input_buffer_next_char(input_buffer *ibuf) +{ + assert(ibuf->pos <= ibuf->len); + + return *(ibuf->text + ibuf->pos++); + +} + + +/****************************************************************************** +* * +* Paramètres : ibuf = tampon de données à consulter. * +* pos = sauvegarde de la tête de lecture. [OUT] * +* * +* Description : Note la position courante de la tête de lecture. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void save_input_buffer_pos(const input_buffer *ibuf, size_t *pos) +{ + *pos = ibuf->pos; + +} + + +/****************************************************************************** +* * +* Paramètres : ibuf = tampon de données à consulter. * +* pos = tête de lecture à définir pour le tampon courant. * +* * +* Description : Restaure la position de la tête de lecture. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void restore_input_buffer_pos(input_buffer *ibuf, size_t pos) +{ + assert(pos <= ibuf->len); + + ibuf->pos = pos; + +} diff --git a/src/common/ibuf.h b/src/common/ibuf.h new file mode 100644 index 0000000..b57e374 --- /dev/null +++ b/src/common/ibuf.h @@ -0,0 +1,71 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ibuf.h - prototypes pour la lecture progressive d'un tampon de données + * + * Copyright (C) 2018 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _COMMON_IBUF_H +#define _COMMON_IBUF_H + + +#include <stdint.h> +#include <sys/types.h> + + + +/* Rassemblement de données d'un tampon */ +typedef struct _input_buffer +{ + union + { + const char *text; /* Contenu textuel disponible */ + const uint8_t *data; /* Données brutes à traiter */ + }; + + size_t len; /* Quantité d'octets présents */ + size_t pos; /* Position de tête de lecture */ + +} input_buffer; + + +/* Initialise un contenu textuel pour une lecture ultérieure. */ +void init_text_input_buffer(input_buffer *, const char *); + +/* Compte le nombre d'octets encore non lus. */ +size_t count_input_buffer_remaining(const input_buffer *); + +/* Avance la tête de lecture dans le tampon de données. */ +void advance_input_buffer(input_buffer *, size_t); + +/* Fournit un accès brut au niveau de la tête de lecture. */ +const char *get_input_buffer_text_access(const input_buffer *); + +/* Fournit et avance la tête de lecture courante. */ +char text_input_buffer_next_char(input_buffer *); + +/* Note la position courante de la tête de lecture. */ +void save_input_buffer_pos(const input_buffer *, size_t *); + +/* Restaure la position de la tête de lecture. */ +void restore_input_buffer_pos(input_buffer *, size_t); + + + +#endif /* _COMMON_IBUF_H */ diff --git a/src/common/packed.c b/src/common/packed.c index 03796b1..d09feea 100644 --- a/src/common/packed.c +++ b/src/common/packed.c @@ -40,7 +40,7 @@ * * * Paramètres : pbuf = paquet de données à initialiser. [OUT] * * * -* Description : Intialise un paquet réseau pour une constitution. * +* Description : Initialise un paquet réseau pour une constitution. * * * * Retour : - * * * diff --git a/src/common/packed.h b/src/common/packed.h index bb12a1f..b1f9d73 100644 --- a/src/common/packed.h +++ b/src/common/packed.h @@ -46,7 +46,7 @@ typedef struct _packed_buffer } packed_buffer; -/* Intialise un paquet réseau pour une constitution. */ +/* Initialise un paquet réseau pour une constitution. */ void init_packed_buffer(packed_buffer *); /* Efface les données contenues par un paquet réseau. */ diff --git a/src/common/utf8.c b/src/common/utf8.c new file mode 100644 index 0000000..401b0a3 --- /dev/null +++ b/src/common/utf8.c @@ -0,0 +1,150 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * utf8.c - support minimaliste mais adapté de l'encodage UTF-8 + * + * Copyright (C) 2018 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "utf8.h" + + + +/****************************************************************************** +* * +* Paramètres : text = position courante dans une chaîne de caractères. * +* len = nombre d'octets de cette même chaîne. * +* consumed = nombre d'octets lus pendant l'opération. [OUT] * +* * +* Description : Procède à la lecture d'un caractère dans une chaîne en UTF-8.* +* * +* Retour : Caractère sur 32 bits lu ou code d'erreur en cas de soucis. * +* * +* Remarques : - * +* * +******************************************************************************/ + +unichar_t decode_utf8_char(const char *text, size_t len, size_t *consumed) +{ + unichar_t result; /* Valeur à retourner */ + size_t expected; /* Quantité à traiter */ + unichar_t minval; /* Valeur codée minimale */ + size_t i; /* Boucle de parcours */ + + result = text[0]; + + /** + * ASCII ? + */ + if (result < 0x80) + { + *consumed = 1; + goto duc_done; + } + + /** + * Deux caractères (au moins) doivent être présents. + * Le premier mot doit donc au moins commencer par 0b1100 = 0xc. + */ + else if (result < 0xc0) + { + result = UTF8_ERROR_MALFORMED; + goto duc_done; + } + + /** + * Valeur inférieure à 0xe, donc taille inférieure à 3 (0b1110). + */ + else if (result < 0xe0) + { + expected = 2; + result &= 0x1f; + minval = 1 << 7; + } + + /** + * Valeur inférieure à 0xf0, donc taille inférieure à 4 (0b11110000). + */ + else if (result < 0xf0) + { + expected = 3; + result &= 0x0f; + minval = 1 << 11; + } + + /** + * Valeur inférieure à 0xf8, donc taille inférieure à 5 (0b11111000). + */ + else if (result < 0xf8) + { + expected = 4; + result &= 0x07; + minval = 1 << 16; + } + + /** + * Erreur : l'encodage UTF-8 ne dépasse pas 4 octets. + */ + else + { + result = UTF8_ERROR_TOO_LONG; + goto duc_done; + } + + /** + * Erreur : pas assez de données. + */ + if (expected > len) + { + result = UTF8_ERROR_TOO_LONG; + goto duc_done; + } + + /** + * Intégration des octets restants, avec vérifications qu'ils participent + * bien à la constitution de la valeur finale. + */ + for (i = 1; i < expected; i++) + { + if ((text[i] & 0xc0) != 0x80) + { + result = UTF8_ERROR_MISSING; + goto duc_done; + } + + result <<= 6; + result |= (text[i] & 0x3f); + + } + + /** + * Validation finale. + */ + if (result < minval) + { + result = UTF8_ERROR_WASTING; + goto duc_done; + } + + *consumed = expected; + + duc_done: + + return result; + +} diff --git a/src/common/utf8.h b/src/common/utf8.h new file mode 100644 index 0000000..b312cd5 --- /dev/null +++ b/src/common/utf8.h @@ -0,0 +1,55 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * utf8.h - prototypes pour un support minimaliste mais adapté de l'encodage UTF-8 + * + * Copyright (C) 2018 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _COMMON_UTF8_H +#define _COMMON_UTF8_H + + +#include <stdint.h> +#include <sys/types.h> + + + +/* Représentation d'un caractère */ +typedef uint32_t unichar_t; + + +/** + * Erreurs qu'il est possible de rencontrer. + */ + +#define UTF8_ERROR_MALFORMED ((unichar_t)-1) +#define UTF8_ERROR_TOO_LONG ((unichar_t)-2) +#define UTF8_ERROR_TRUNCATED ((unichar_t)-3) +#define UTF8_ERROR_MISSING ((unichar_t)-4) +#define UTF8_ERROR_WASTING ((unichar_t)-5) + +#define IS_UTF8_ERROR(v) (v & (1u << 31)) + + +/* Procède à la lecture d'un caractère dans une chaîne en UTF-8. */ +unichar_t decode_utf8_char(const char *, size_t, size_t *); + + + +#endif /* _COMMON_UTF8_H */ |