From 3ad8e821ec6a6e8408a9fc737b385aa863c67123 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sat, 8 Dec 2018 12:06:17 +0100 Subject: Fixed one UAF when dealing with line text segments. --- src/glibext/gbufferline.c | 8 ++++---- src/glibext/gbufferline.h | 4 ++-- src/glibext/gbufferview.c | 9 +++++++-- src/glibext/linecolumn.c | 4 +++- src/glibext/linesegment.c | 21 ++++++++++++++++++++- src/glibext/linesegment.h | 3 +++ 6 files changed, 39 insertions(+), 10 deletions(-) diff --git a/src/glibext/gbufferline.c b/src/glibext/gbufferline.c index 2a3a04f..3dcbbd4 100644 --- a/src/glibext/gbufferline.c +++ b/src/glibext/gbufferline.c @@ -1029,14 +1029,14 @@ gint g_buffer_line_compute_max_width(const GBufferLine *line, BufferLineColumn i * * ******************************************************************************/ -const line_segment *g_buffer_line_get_segment_from_coord(const GBufferLine *line, const col_coord_t *coord) +line_segment *g_buffer_line_get_segment_from_coord(const GBufferLine *line, const col_coord_t *coord) { line_segment *result; /* Trouvaille à retourner */ if (coord->column < BLC_COUNT) result = get_line_column_content_from_index(&line->columns[coord->column], coord->index); else - result = false; + result = NULL; return result; @@ -1269,9 +1269,9 @@ bool g_buffer_line_get_coord_at(const GBufferLine *line, const line_width_summar * * ******************************************************************************/ -const line_segment *g_buffer_line_get_segment_at(const GBufferLine *line, const line_width_summary *summary, const GDisplayOptions *options, const line_width_summary *offsets, gint *base, gint *offset, GdkScrollDirection dir, bool force) +line_segment *g_buffer_line_get_segment_at(const GBufferLine *line, const line_width_summary *summary, const GDisplayOptions *options, const line_width_summary *offsets, gint *base, gint *offset, GdkScrollDirection dir, bool force) { - const line_segment *result; /* Trouvaille à retourner */ + line_segment *result; /* Trouvaille à retourner */ col_coord_t coord; /* Emplacement du contenu visé */ bool status; /* Bilan de la localisation */ diff --git a/src/glibext/gbufferline.h b/src/glibext/gbufferline.h index 1d36d95..fe5cede 100644 --- a/src/glibext/gbufferline.h +++ b/src/glibext/gbufferline.h @@ -196,13 +196,13 @@ void g_buffer_line_collect_widths(GBufferLine *, line_width_summary *); gint g_buffer_line_compute_max_width(const GBufferLine *, BufferLineColumn, const line_width_summary *, const line_width_summary *); /* Fournit le segment présent à une position donnée. */ -const line_segment *g_buffer_line_get_segment_from_coord(const GBufferLine *, const col_coord_t *); +line_segment *g_buffer_line_get_segment_from_coord(const GBufferLine *, const col_coord_t *); /* Fournit les coordonnées correspondant à une abscisse donnée. */ bool g_buffer_line_get_coord_at(const GBufferLine *, const line_width_summary *, const GDisplayOptions *, const line_width_summary *, gint *, gint *, GdkScrollDirection, bool, col_coord_t *); /* Donne le segment présent à une abscisse donnée. */ -const line_segment *g_buffer_line_get_segment_at(const GBufferLine *, const line_width_summary *, const GDisplayOptions *, const line_width_summary *, gint *, gint *, GdkScrollDirection, bool); +line_segment *g_buffer_line_get_segment_at(const GBufferLine *, const line_width_summary *, const GDisplayOptions *, const line_width_summary *, gint *, gint *, GdkScrollDirection, bool); /* Donne le créateur présent à une abscisse donnée. */ GObject *g_buffer_line_get_creator_at(const GBufferLine *, const line_width_summary *, const GDisplayOptions *, const line_width_summary *, gint *, gint *, GdkScrollDirection, bool); diff --git a/src/glibext/gbufferview.c b/src/glibext/gbufferview.c index bc8cf54..f5adc9d 100644 --- a/src/glibext/gbufferview.c +++ b/src/glibext/gbufferview.c @@ -725,7 +725,7 @@ static bool _g_buffer_view_move_caret(GBufferView *view, const GBufferLine *line line_width_summary summary; /* Résumé concis des largeurs */ gint base; /* Position absolue de segment */ col_coord_t coord; /* Coordonnées en interne */ - const line_segment *segment; /* Bribe de texte trouvée */ + line_segment *segment; /* Bribe de texte trouvée */ result = false; @@ -751,6 +751,8 @@ static bool _g_buffer_view_move_caret(GBufferView *view, const GBufferLine *line result = move_caret_on_line_segment(segment, &offset, ctrl, dir); + release_line_segment(segment); + } /* Tentative de déplacement chez le segment voisin ? */ @@ -1031,7 +1033,7 @@ bool g_buffer_view_highlight_segments(GBufferView *view, gint x, gint y, const G size_t index; /* Indice de ligne de tampon */ GBufferLine *line; /* Ligne à la position courante*/ line_width_summary summary; /* Résumé concis des largeurs */ - const line_segment *segment; /* Segment sélectionnable */ + line_segment *segment; /* Segment sélectionnable */ /* Réinitialisation */ @@ -1075,7 +1077,10 @@ bool g_buffer_view_highlight_segments(GBufferView *view, gint x, gint y, const G /* Conclusion */ if (segment != NULL) + { result |= add_segment_content_to_selection_list(view->highlighted, segment); + release_line_segment(segment); + } if (result) g_signal_emit_by_name(view, "need-redraw"); diff --git a/src/glibext/linecolumn.c b/src/glibext/linecolumn.c index 2d24926..6b6937f 100644 --- a/src/glibext/linecolumn.c +++ b/src/glibext/linecolumn.c @@ -153,7 +153,7 @@ size_t append_text_to_line_column(line_column *column, const char *text, size_t segment = get_new_line_segment(type, text, length); - column->segments = (line_segment **)realloc(column->segments, ++column->count * sizeof(line_segment *)); + column->segments = realloc(column->segments, ++column->count * sizeof(line_segment *)); column->segments[result] = segment; @@ -396,6 +396,8 @@ line_segment *get_line_column_content_from_index(const line_column *column, size result = column->segments[index]; + ref_line_segment(result); + return result; } diff --git a/src/glibext/linesegment.c b/src/glibext/linesegment.c index dc4a128..557dff2 100644 --- a/src/glibext/linesegment.c +++ b/src/glibext/linesegment.c @@ -466,6 +466,25 @@ line_segment *get_new_line_segment(RenderingTagType type, const char *text, size /****************************************************************************** * * +* Paramètres : segment = fragment de texte à traiter. * +* * +* Description : Augmente le compteur de références d'un fragment de texte. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void ref_line_segment(line_segment *segment) +{ + segment->ref_count++; + +} + + +/****************************************************************************** +* * * Paramètres : segment = fragment de texte à libérer de la mémoire. * * * * Description : Retire une utilisation à un fragment de texte. * @@ -1037,7 +1056,7 @@ bool add_segment_content_to_selection_list(segcnt_list *list, const line_segment if (result) { - list->hashes = (fnv64_t *)realloc(list->hashes, ++list->count * sizeof(fnv64_t)); + list->hashes = realloc(list->hashes, ++list->count * sizeof(fnv64_t)); list->hashes[list->count - 1] = segment->hash; diff --git a/src/glibext/linesegment.h b/src/glibext/linesegment.h index a0b8e91..c6deb38 100644 --- a/src/glibext/linesegment.h +++ b/src/glibext/linesegment.h @@ -114,6 +114,9 @@ typedef enum _RenderingTagType /* Crée un nouveau fragment de texte avec des propriétés. */ line_segment *get_new_line_segment(RenderingTagType, const char *, size_t); +/* Augmente le compteur de références d'un fragment de texte. */ +void ref_line_segment(line_segment *); + /* Retire une utilisation à un fragment de texte. */ void release_line_segment(line_segment *); -- cgit v0.11.2-87-g4458