From 464e9b7d0b8e4e1d6c278be71f87778729213bc8 Mon Sep 17 00:00:00 2001 From: Nick Treleaven Date: Mon, 2 Oct 2006 15:22:29 +0000 Subject: [PATCH] Change sci_get_line to return a NULL terminated string. Fix memory leak and possible invalid read in sci_cb_auto_latex(). git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@861 ea778897-0a13-0410-b9d1-a72fbfd435f5 --- ChangeLog | 4 ++++ src/callbacks.c | 3 +-- src/document.c | 7 ++----- src/sci_cb.c | 36 ++++++++++++------------------------ src/sciwrappers.c | 11 +++++++++-- src/sciwrappers.h | 2 +- 6 files changed, 29 insertions(+), 34 deletions(-) diff --git a/ChangeLog b/ChangeLog index 83ebbd6f..bf08446a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,10 @@ src/makefile.win32, src/Makefile.am, po/POTFILES.in: Move global tags code to symbols.c. Added symbols_global_tags_loaded(), symbols_get_global_keywords(). + * src/callbacks.c, src/sci_cb.c, src/sciwrappers.c, src/sciwrappers.h, + src/document.c: + Change sci_get_line to return a NULL terminated string. + Fix memory leak and possible invalid read in sci_cb_auto_latex(). 2006-10-01 Enrico Tröger diff --git a/src/callbacks.c b/src/callbacks.c index 3b6c02ef..5e7f3c6f 100644 --- a/src/callbacks.c +++ b/src/callbacks.c @@ -1296,8 +1296,7 @@ on_find_usage1_activate (GtkMenuItem *menuitem, if (pos == -1) break; line = sci_get_line_from_position(doc_list[i].sci, pos); - buffer = g_malloc0(sci_get_line_length(doc_list[i].sci, line) + 1); - sci_get_line(doc_list[i].sci, line, buffer); + buffer = sci_get_line(doc_list[i].sci, line); if (doc_list[i].file_name == NULL) short_file_name = g_strdup(GEANY_STRING_UNTITLED); diff --git a/src/document.c b/src/document.c index e305c951..7974deb0 100644 --- a/src/document.c +++ b/src/document.c @@ -1335,12 +1335,9 @@ void document_set_indicator(gint idx, gint line) sci_get_line_length(doc_list[idx].sci, line) == utils_get_eol_char_len(idx)) return; - len = end - start; - linebuf = g_malloc(len); - // don't set the indicator on whitespace - sci_get_line(doc_list[idx].sci, line, linebuf); - if (linebuf == NULL) return; + len = end - start; + linebuf = sci_get_line(doc_list[idx].sci, line); while (isspace(linebuf[i])) i++; while (isspace(linebuf[len-1])) len--; diff --git a/src/sci_cb.c b/src/sci_cb.c index 44e7c047..168924b5 100644 --- a/src/sci_cb.c +++ b/src/sci_cb.c @@ -330,9 +330,7 @@ void sci_cb_get_indent(ScintillaObject *sci, gint pos, gboolean use_this_line) if (! use_this_line) prev_line--; len = sci_get_line_length(sci, prev_line); - linebuf = g_malloc(len + 1); - sci_get_line(sci, prev_line, linebuf); - linebuf[len] = '\0'; + linebuf = sci_get_line(sci, prev_line); for (i = 0; i < len; i++) { @@ -438,8 +436,7 @@ void sci_cb_close_block(gint idx, gint pos) utils_get_eol_char_len(document_find_by_sci(sci)); // check that the line is empty, to not kill text in the line - line_buf = g_malloc(line_len + 1); - sci_get_line(sci, line, line_buf); + line_buf = sci_get_line(sci, line); line_buf[line_len - eol_char_len] = '\0'; while (x < (line_len - eol_char_len)) { @@ -469,11 +466,10 @@ void sci_cb_find_current_word(ScintillaObject *sci, gint pos, gchar *word, size_ gint line_start = sci_get_position_from_line(sci, line); gint startword = pos - line_start; gint endword = pos - line_start; - gchar *chunk = g_malloc(sci_get_line_length(sci, line) + 1); + gchar *chunk; word[0] = '\0'; - sci_get_line(sci, line, chunk); - chunk[sci_get_line_length(sci, line)] = '\0'; + chunk = sci_get_line(sci, line); while (startword > 0 && strchr(GEANY_WORDCHARS, chunk[startword - 1])) startword--; @@ -664,8 +660,7 @@ gboolean sci_cb_start_auto_complete(gint idx, gint pos, gboolean force) else if (lexer == SCLEX_RUBY && style == SCE_MAKE_COMMENT) return FALSE; - linebuf = g_malloc(line_len + 1); - sci_get_line(sci, line, linebuf); + linebuf = sci_get_line(sci, line); // find the start of the current word while ((startword > 0) && (strchr(GEANY_WORDCHARS, linebuf[startword - 1]))) @@ -706,8 +701,7 @@ void sci_cb_auto_latex(gint idx, gint pos) gint i, start; // get the line - buf = g_malloc0(line_len + 1); - sci_get_line(sci, line, buf); + buf = sci_get_line(sci, line); // get to the first non-blank char (some kind of ltrim()) start = 0; @@ -722,7 +716,7 @@ void sci_cb_auto_latex(gint idx, gint pos) // take also "\begingroup" (or whatever there can be) and append "\endgroup" and so on. i = start + 6; - while (buf[i] != '{' && j < (sizeof(full_cmd) - 1)) + while (i < line_len && buf[i] != '{' && j < (sizeof(full_cmd) - 1)) { // copy all between "\begin" and "{" to full_cmd full_cmd[j] = buf[i]; i++; @@ -757,13 +751,11 @@ void sci_cb_auto_latex(gint idx, gint pos) SSM(sci, SCI_INSERTTEXT, pos, (sptr_t) construct); sci_goto_pos(sci, pos + 1, TRUE); g_free(construct); - g_free(buf); g_free(eol); } - else - { // later there could be some else ifs for other keywords - return; - } + // later there could be some else ifs for other keywords + + g_free(buf); } } @@ -1107,9 +1099,7 @@ static void real_uncomment_multiline(gint idx) // check whether the line is empty and can be deleted line = sci_get_line_from_position(doc_list[idx].sci, pos); len = sci_get_line_length(doc_list[idx].sci, line); - linebuf = g_malloc(len + 1); - sci_get_line(doc_list[idx].sci, line, linebuf); - linebuf[len] = '\0'; + linebuf = sci_get_line(doc_list[idx].sci, line); x = 0; while (linebuf[x] != '\0' && isspace(linebuf[x])) x++; if (x == len) SSM(doc_list[idx].sci, SCI_LINEDELETE, 0, 0); @@ -1122,9 +1112,7 @@ static void real_uncomment_multiline(gint idx) // check whether the line is empty and can be deleted line = sci_get_line_from_position(doc_list[idx].sci, pos); len = sci_get_line_length(doc_list[idx].sci, line); - linebuf = g_malloc(len + 1); - sci_get_line(doc_list[idx].sci, line, linebuf); - linebuf[len] = '\0'; + linebuf = sci_get_line(doc_list[idx].sci, line); x = 0; while (linebuf[x] != '\0' && isspace(linebuf[x])) x++; if (x == len) SSM(doc_list[idx].sci, SCI_LINEDELETE, 0, 0); diff --git a/src/sciwrappers.c b/src/sciwrappers.c index fbee80f1..ddc09fdd 100644 --- a/src/sciwrappers.c +++ b/src/sciwrappers.c @@ -469,11 +469,18 @@ gint sci_get_line_length(ScintillaObject* sci,gint line) } -void sci_get_line(ScintillaObject* sci, gint line, gchar* text) +// Returns: a NULL-terminated copy of the line text +gchar *sci_get_line(ScintillaObject* sci, gint line_num) { - SSM(sci,SCI_GETLINE, line, (sptr_t) text); + gint len = sci_get_line_length(sci, line_num); + gchar *linebuf = g_malloc(len + 1); + + SSM(sci, SCI_GETLINE, line_num, (sptr_t) linebuf); + linebuf[len] = '\0'; + return linebuf; } + // the last char will be null terminated void sci_get_text(ScintillaObject* sci, gint len, gchar* text) { diff --git a/src/sciwrappers.h b/src/sciwrappers.h index f727873d..924bc1d5 100644 --- a/src/sciwrappers.h +++ b/src/sciwrappers.h @@ -81,7 +81,7 @@ gint sci_get_length (ScintillaObject* sci); void sci_get_text (ScintillaObject* sci,gint len,gchar* text); void sci_get_selected_text (ScintillaObject* sci, gchar* text); gint sci_get_selected_text_length(ScintillaObject* sci); -void sci_get_line (ScintillaObject* sci, gint line, gchar* text); +gchar * sci_get_line (ScintillaObject* sci, gint line_num); gint sci_get_line_length (ScintillaObject* sci, gint line); gint sci_get_line_count ( ScintillaObject* sci ); void sci_get_xy_from_position (ScintillaObject* sci,gint pos, gint* x, gint* y);