~mdw
/
tig
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Improve string buffer copy safety
[tig]
/
tig.c
diff --git
a/tig.c
b/tig.c
index
bfa8ae8
..
44fcb1b
100644
(file)
--- a/
tig.c
+++ b/
tig.c
@@
-145,16
+145,22
@@
set_from_int_map(struct int_map *map, size_t map_size,
*/
static inline void
*/
static inline void
-string_ncopy
(char *dst, const char *src, size_t dst
len)
+string_ncopy
_do(char *dst, size_t dstlen, const char *src, size_t src
len)
{
{
- strncpy(dst, src, dstlen - 1);
-
dst[dstlen - 1] = 0
;
+ if (srclen > dstlen - 1)
+
srclen = dstlen - 1
;
+ strncpy(dst, src, srclen);
+ dst[srclen] = 0;
}
}
-/* Shorthand for safely copying into a fixed buffer. */
+/* Shorthands for safely copying into a fixed buffer. */
+
#define string_copy(dst, src) \
#define string_copy(dst, src) \
- string_ncopy(dst, src, sizeof(dst))
+ string_ncopy_do(dst, sizeof(dst), src, sizeof(dst))
+
+#define string_ncopy(dst, src, srclen) \
+ string_ncopy_do(dst, sizeof(dst), src, srclen)
static char *
chomp_string(char *name)
static char *
chomp_string(char *name)
@@
-675,7
+681,7
@@
static struct keybinding default_keybindings[] = {
{ 'd', REQ_VIEW_DIFF },
{ 'l', REQ_VIEW_LOG },
{ 't', REQ_VIEW_TREE },
{ 'd', REQ_VIEW_DIFF },
{ 'l', REQ_VIEW_LOG },
{ 't', REQ_VIEW_TREE },
- { '
b
', REQ_VIEW_BLOB },
+ { '
f
', REQ_VIEW_BLOB },
{ 'p', REQ_VIEW_PAGER },
{ 'h', REQ_VIEW_HELP },
{ 'p', REQ_VIEW_PAGER },
{ 'h', REQ_VIEW_HELP },
@@
-714,7
+720,7
@@
static struct keybinding default_keybindings[] = {
{ 'z', REQ_STOP_LOADING },
{ 'v', REQ_SHOW_VERSION },
{ 'r', REQ_SCREEN_REDRAW },
{ 'z', REQ_STOP_LOADING },
{ 'v', REQ_SHOW_VERSION },
{ 'r', REQ_SCREEN_REDRAW },
- { '
n
', REQ_TOGGLE_LINENO },
+ { '
.
', REQ_TOGGLE_LINENO },
{ 'g', REQ_TOGGLE_REV_GRAPH },
{ ':', REQ_PROMPT },
{ 'g', REQ_TOGGLE_REV_GRAPH },
{ ':', REQ_PROMPT },
@@
-1684,7
+1690,7
@@
search_view(struct view *view, enum request request, const char *search)
char buf[SIZEOF_STR] = "unknown error";
regerror(regex_err, &view->regex, buf, sizeof(buf));
char buf[SIZEOF_STR] = "unknown error";
regerror(regex_err, &view->regex, buf, sizeof(buf));
- report("Search failed: %s", buf);
;
+ report("Search failed: %s", buf);
return;
}
return;
}
@@
-1731,8
+1737,7
@@
begin_update(struct view *view)
if (strcmp(view->vid, view->id))
opt_path[0] = 0;
if (strcmp(view->vid, view->id))
opt_path[0] = 0;
- if (snprintf(view->cmd, sizeof(view->cmd), format, id, opt_path)
- >= sizeof(view->cmd))
+ if (!string_format(view->cmd, format, id, opt_path))
return FALSE;
} else {
return FALSE;
} else {
@@
-2205,8
+2210,7
@@
pager_draw(struct view *view, struct line *line, unsigned int lineno)
string_copy(ref_commit, view->ref);
} else if (type == LINE_TREE_DIR || type == LINE_TREE_FILE) {
string_copy(ref_commit, view->ref);
} else if (type == LINE_TREE_DIR || type == LINE_TREE_FILE) {
- strncpy(view->ref, text + STRING_SIZE("100644 blob "), 41);
- view->ref[40] = 0;
+ string_ncopy(view->ref, text + STRING_SIZE("100644 blob "), 40);
string_copy(ref_blob, view->ref);
}
string_copy(ref_blob, view->ref);
}
@@
-2452,6
+2456,7
@@
tree_read(struct view *view, char *text)
char buf[SIZEOF_STR];
unsigned long pos;
enum line_type type;
char buf[SIZEOF_STR];
unsigned long pos;
enum line_type type;
+ bool first_read = view->lines == 0;
if (textlen <= SIZEOF_TREE_ATTR)
return FALSE;
if (textlen <= SIZEOF_TREE_ATTR)
return FALSE;
@@
-2459,10
+2464,9
@@
tree_read(struct view *view, char *text)
type = text[STRING_SIZE("100644 ")] == 't'
? LINE_TREE_DIR : LINE_TREE_FILE;
type = text[STRING_SIZE("100644 ")] == 't'
? LINE_TREE_DIR : LINE_TREE_FILE;
- /* The first time around ... */
- if (!view->lines) {
+ if (first_read) {
/* Add path info line */
/* Add path info line */
- if (s
nprintf(buf, sizeof(buf), "Directory path /%s", opt_path) < sizeof(buf
) &&
+ if (s
tring_format(buf, "Directory path /%s", opt_path
) &&
realloc_lines(view, view->line_size + 1) &&
pager_read(view, buf))
view->line[view->lines - 1].type = LINE_DEFAULT;
realloc_lines(view, view->line_size + 1) &&
pager_read(view, buf))
view->line[view->lines - 1].type = LINE_DEFAULT;
@@
-2471,7
+2475,7
@@
tree_read(struct view *view, char *text)
/* Insert "link" to parent directory. */
if (*opt_path &&
/* Insert "link" to parent directory. */
if (*opt_path &&
- s
nprintf(buf, sizeof(buf), TREE_UP_FORMAT, view->ref) < sizeof(bu
f) &&
+ s
tring_format(buf, TREE_UP_FORMAT, view->re
f) &&
realloc_lines(view, view->line_size + 1) &&
pager_read(view, buf))
view->line[view->lines - 1].type = LINE_TREE_DIR;
realloc_lines(view, view->line_size + 1) &&
pager_read(view, buf))
view->line[view->lines - 1].type = LINE_TREE_DIR;
@@
-2518,6
+2522,10
@@
tree_read(struct view *view, char *text)
if (!pager_read(view, text))
return FALSE;
if (!pager_read(view, text))
return FALSE;
+ /* Move the current line to the first tree entry. */
+ if (first_read)
+ view->lineno++;
+
view->line[view->lines - 1].type = type;
return TRUE;
}
view->line[view->lines - 1].type = type;
return TRUE;
}
@@
-2544,9
+2552,13
@@
tree_enter(struct view *view, struct line *line)
} else {
size_t pathlen = strlen(opt_path);
} else {
size_t pathlen = strlen(opt_path);
+ size_t origlen = pathlen;
char *basename = data + SIZEOF_TREE_ATTR;
char *basename = data + SIZEOF_TREE_ATTR;
- string_format_from(opt_path, &pathlen, "%s/", basename);
+ if (string_format_from(opt_path, &pathlen, "%s/", basename)) {
+ opt_path[origlen] = 0;
+ return TRUE;
+ }
}
/* Trees and subtrees share the same ID, so they are not not
}
/* Trees and subtrees share the same ID, so they are not not
@@
-3416,7
+3428,7
@@
main(int argc, char *argv[])
if (*opt_codeset && strcmp(opt_codeset, opt_encoding)) {
opt_iconv = iconv_open(opt_codeset, opt_encoding);
if (*opt_codeset && strcmp(opt_codeset, opt_encoding)) {
opt_iconv = iconv_open(opt_codeset, opt_encoding);
- if (opt_iconv ==
(iconv_t) -1
)
+ if (opt_iconv ==
ICONV_NONE
)
die("Failed to initialize character set conversion");
}
die("Failed to initialize character set conversion");
}