mirror of
https://github.com/janet-lang/janet
synced 2024-12-29 09:50:27 +00:00
Address some issues found in lgtm
Caught a few potentially issues with overflows, as well as use of unsafe function localtime.
This commit is contained in:
parent
8ee54e887f
commit
a18a251d16
@ -1668,7 +1668,8 @@
|
||||
:on-compile-error - callback when compilation fails - default is bad-compile\n\t
|
||||
:compile-only - only compile the source, do not execute it - default is false\n\t
|
||||
:on-status - callback when a value is evaluated - default is debug/stacktrace\n\t
|
||||
:fiber-flags - what flags to wrap the compilation fiber with. Default is :ia."
|
||||
:fiber-flags - what flags to wrap the compilation fiber with. Default is :ia.\n\t
|
||||
:expander - an optional function that is called on each top level form before being compiled."
|
||||
[opts]
|
||||
|
||||
(def {:env env
|
||||
@ -1678,7 +1679,8 @@
|
||||
:on-parse-error on-parse-error
|
||||
:fiber-flags guard
|
||||
:compile-only compile-only
|
||||
:source where} opts)
|
||||
:source where
|
||||
:expander expand} opts)
|
||||
(default env (fiber/getenv (fiber/current)))
|
||||
(default chunks (fn [buf p] (getline "" buf)))
|
||||
(default compile-only false)
|
||||
@ -1695,6 +1697,7 @@
|
||||
|
||||
# Evaluate 1 source form in a protected manner
|
||||
(defn eval1 [source]
|
||||
(def source (if expand (expand source) source))
|
||||
(var good true)
|
||||
(def f
|
||||
(fiber/new
|
||||
@ -1718,6 +1721,7 @@
|
||||
# Loop
|
||||
(def buf @"")
|
||||
(while going
|
||||
(if (env :exit) (break))
|
||||
(buffer/clear buf)
|
||||
(chunks buf p)
|
||||
(var pindex 0)
|
||||
@ -1740,6 +1744,13 @@
|
||||
|
||||
env)
|
||||
|
||||
(defn quit
|
||||
"Tries to exit from the current repl or context. Does not always exit the application.
|
||||
Works by setting the :exit dynamic binding to true."
|
||||
[]
|
||||
(setdyn :exit true)
|
||||
"Bye!")
|
||||
|
||||
(defn eval-string
|
||||
"Evaluates a string in the current environment. If more control over the
|
||||
environment is needed, use run-context."
|
||||
@ -2005,7 +2016,7 @@
|
||||
(debug/stacktrace f x)
|
||||
(print ```
|
||||
|
||||
entering debugger - Ctrl-D to exit
|
||||
entering debugger - (quit) or Ctrl-D to exit
|
||||
_fiber is bound to the suspended fiber
|
||||
|
||||
```)
|
||||
|
@ -64,7 +64,7 @@ void janet_array_ensure(JanetArray *array, int32_t capacity, int32_t growth) {
|
||||
Janet *newData;
|
||||
Janet *old = array->data;
|
||||
if (capacity <= array->capacity) return;
|
||||
int64_t new_capacity = capacity * growth;
|
||||
int64_t new_capacity = ((int64_t) capacity) * growth;
|
||||
if (new_capacity > INT32_MAX) new_capacity = INT32_MAX;
|
||||
capacity = (int32_t) new_capacity;
|
||||
newData = realloc(old, capacity * sizeof(Janet));
|
||||
|
@ -59,7 +59,7 @@ void janet_buffer_ensure(JanetBuffer *buffer, int32_t capacity, int32_t growth)
|
||||
uint8_t *new_data;
|
||||
uint8_t *old = buffer->data;
|
||||
if (capacity <= buffer->capacity) return;
|
||||
int64_t big_capacity = capacity * growth;
|
||||
int64_t big_capacity = ((int64_t) capacity) * growth;
|
||||
capacity = big_capacity > INT32_MAX ? INT32_MAX : (int32_t) big_capacity;
|
||||
janet_vm_next_collection += capacity - buffer->capacity;
|
||||
new_data = realloc(old, capacity * sizeof(uint8_t));
|
||||
|
@ -477,13 +477,19 @@ static Janet os_date(int32_t argc, Janet *argv) {
|
||||
janet_arity(argc, 0, 1);
|
||||
(void) argv;
|
||||
time_t t;
|
||||
struct tm t_infos;
|
||||
struct tm *t_info;
|
||||
if (argc) {
|
||||
t = (time_t) janet_getinteger64(argv, 0);
|
||||
} else {
|
||||
time(&t);
|
||||
}
|
||||
t_info = localtime(&t);
|
||||
#ifdef JANET_WINDOWS
|
||||
localtime_s(&t_infos, &t);
|
||||
t_info = &t_infos;
|
||||
#else
|
||||
t_info = localtime_r(&t, &t_infos);
|
||||
#endif
|
||||
JanetKV *st = janet_struct_begin(9);
|
||||
janet_struct_put(st, janet_ckeywordv("seconds"), janet_wrap_number(t_info->tm_sec));
|
||||
janet_struct_put(st, janet_ckeywordv("minutes"), janet_wrap_number(t_info->tm_min));
|
||||
|
@ -30,7 +30,8 @@ void *janet_v_grow(void *v, int32_t increment, int32_t itemsize) {
|
||||
int32_t dbl_cur = (NULL != v) ? 2 * janet_v__cap(v) : 0;
|
||||
int32_t min_needed = janet_v_count(v) + increment;
|
||||
int32_t m = dbl_cur > min_needed ? dbl_cur : min_needed;
|
||||
int32_t *p = (int32_t *) janet_srealloc(v ? janet_v__raw(v) : 0, itemsize * m + sizeof(int32_t) * 2);
|
||||
size_t newsize = ((size_t) itemsize) * m + sizeof(int32_t) * 2;
|
||||
int32_t *p = (int32_t *) janet_srealloc(v ? janet_v__raw(v) : 0, newsize);
|
||||
if (!v) p[1] = 0;
|
||||
p[0] = m;
|
||||
return p + 2;
|
||||
|
@ -892,12 +892,12 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in, JanetFiberStatus status)
|
||||
Janet fv = stack[C];
|
||||
vm_assert_type(fv, JANET_FIBER);
|
||||
JanetFiber *f = janet_unwrap_fiber(fv);
|
||||
JanetFiberStatus status = janet_fiber_status(f);
|
||||
if (status > JANET_STATUS_USER9) {
|
||||
JanetFiberStatus sub_status = janet_fiber_status(f);
|
||||
if (sub_status > JANET_STATUS_USER9) {
|
||||
vm_throw("cannot propagate from new or alive fiber");
|
||||
}
|
||||
janet_vm_fiber->child = f;
|
||||
vm_return((int) status, stack[B]);
|
||||
vm_return((int) sub_status, stack[B]);
|
||||
}
|
||||
|
||||
VM_OP(JOP_PUT)
|
||||
|
@ -87,18 +87,18 @@ https://github.com/antirez/linenoise/blob/master/linenoise.c
|
||||
/* static state */
|
||||
#define JANET_LINE_MAX 1024
|
||||
#define JANET_HISTORY_MAX 100
|
||||
static int israwmode = 0;
|
||||
static const char *prompt = "> ";
|
||||
static int plen = 2;
|
||||
static char buf[JANET_LINE_MAX];
|
||||
static int len = 0;
|
||||
static int pos = 0;
|
||||
static int cols = 80;
|
||||
static char *history[JANET_HISTORY_MAX];
|
||||
static int history_count = 0;
|
||||
static int historyi = 0;
|
||||
static int sigint_flag = 0;
|
||||
static struct termios termios_start;
|
||||
static int gbl_israwmode = 0;
|
||||
static const char *gbl_prompt = "> ";
|
||||
static int gbl_plen = 2;
|
||||
static char gbl_buf[JANET_LINE_MAX];
|
||||
static int gbl_len = 0;
|
||||
static int gbl_pos = 0;
|
||||
static int gbl_cols = 80;
|
||||
static char *gbl_history[JANET_HISTORY_MAX];
|
||||
static int gbl_history_count = 0;
|
||||
static int gbl_historyi = 0;
|
||||
static int gbl_sigint_flag = 0;
|
||||
static struct termios gbl_termios_start;
|
||||
|
||||
/* Unsupported terminal list from linenoise */
|
||||
static const char *badterms[] = {
|
||||
@ -121,8 +121,8 @@ static char *sdup(const char *s) {
|
||||
static int rawmode() {
|
||||
struct termios t;
|
||||
if (!isatty(STDIN_FILENO)) goto fatal;
|
||||
if (tcgetattr(STDIN_FILENO, &termios_start) == -1) goto fatal;
|
||||
t = termios_start;
|
||||
if (tcgetattr(STDIN_FILENO, &gbl_termios_start) == -1) goto fatal;
|
||||
t = gbl_termios_start;
|
||||
t.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
|
||||
t.c_oflag &= ~(OPOST);
|
||||
t.c_cflag |= (CS8);
|
||||
@ -130,7 +130,7 @@ static int rawmode() {
|
||||
t.c_cc[VMIN] = 1;
|
||||
t.c_cc[VTIME] = 0;
|
||||
if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &t) < 0) goto fatal;
|
||||
israwmode = 1;
|
||||
gbl_israwmode = 1;
|
||||
return 0;
|
||||
fatal:
|
||||
errno = ENOTTY;
|
||||
@ -139,8 +139,8 @@ fatal:
|
||||
|
||||
/* Disable raw mode */
|
||||
static void norawmode() {
|
||||
if (israwmode && tcsetattr(STDIN_FILENO, TCSAFLUSH, &termios_start) != -1)
|
||||
israwmode = 0;
|
||||
if (gbl_israwmode && tcsetattr(STDIN_FILENO, TCSAFLUSH, &gbl_termios_start) != -1)
|
||||
gbl_israwmode = 0;
|
||||
}
|
||||
|
||||
static int curpos() {
|
||||
@ -171,7 +171,9 @@ static int getcols() {
|
||||
if (cols > start) {
|
||||
char seq[32];
|
||||
snprintf(seq, 32, "\x1b[%dD", cols - start);
|
||||
if (write(STDOUT_FILENO, seq, strlen(seq)) == -1) {}
|
||||
if (write(STDOUT_FILENO, seq, strlen(seq)) == -1) {
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
return cols;
|
||||
} else {
|
||||
@ -182,7 +184,9 @@ failed:
|
||||
}
|
||||
|
||||
static void clear() {
|
||||
if (write(STDOUT_FILENO, "\x1b[H\x1b[2J", 7) <= 0) {}
|
||||
if (write(STDOUT_FILENO, "\x1b[H\x1b[2J", 7) <= 0) {
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void refresh() {
|
||||
@ -190,38 +194,40 @@ static void refresh() {
|
||||
JanetBuffer b;
|
||||
|
||||
/* Keep cursor position on screen */
|
||||
char *_buf = buf;
|
||||
int _len = len;
|
||||
int _pos = pos;
|
||||
while ((plen + _pos) >= cols) {
|
||||
char *_buf = gbl_buf;
|
||||
int _len = gbl_len;
|
||||
int _pos = gbl_pos;
|
||||
while ((gbl_plen + _pos) >= gbl_cols) {
|
||||
_buf++;
|
||||
_len--;
|
||||
_pos--;
|
||||
}
|
||||
while ((plen + _len) > cols) {
|
||||
while ((gbl_plen + _len) > gbl_cols) {
|
||||
_len--;
|
||||
}
|
||||
|
||||
janet_buffer_init(&b, 0);
|
||||
/* Cursor to left edge, prompt and buffer */
|
||||
/* Cursor to left edge, gbl_prompt and buffer */
|
||||
janet_buffer_push_u8(&b, '\r');
|
||||
janet_buffer_push_cstring(&b, prompt);
|
||||
janet_buffer_push_cstring(&b, gbl_prompt);
|
||||
janet_buffer_push_bytes(&b, (uint8_t *) _buf, _len);
|
||||
/* Erase to right */
|
||||
janet_buffer_push_cstring(&b, "\x1b[0K");
|
||||
/* Move cursor to original position. */
|
||||
snprintf(seq, 64, "\r\x1b[%dC", (int)(_pos + plen));
|
||||
snprintf(seq, 64, "\r\x1b[%dC", (int)(_pos + gbl_plen));
|
||||
janet_buffer_push_cstring(&b, seq);
|
||||
if (write(STDOUT_FILENO, b.data, b.count) == -1) {}
|
||||
if (write(STDOUT_FILENO, b.data, b.count) == -1) {
|
||||
exit(1);
|
||||
}
|
||||
janet_buffer_deinit(&b);
|
||||
}
|
||||
|
||||
static int insert(char c) {
|
||||
if (len < JANET_LINE_MAX - 1) {
|
||||
if (len == pos) {
|
||||
buf[pos++] = c;
|
||||
buf[++len] = '\0';
|
||||
if (plen + len < cols) {
|
||||
if (gbl_len < JANET_LINE_MAX - 1) {
|
||||
if (gbl_len == gbl_pos) {
|
||||
gbl_buf[gbl_pos++] = c;
|
||||
gbl_buf[++gbl_len] = '\0';
|
||||
if (gbl_plen + gbl_len < gbl_cols) {
|
||||
/* Avoid a full update of the line in the
|
||||
* trivial case. */
|
||||
if (write(STDOUT_FILENO, &c, 1) == -1) return -1;
|
||||
@ -229,9 +235,9 @@ static int insert(char c) {
|
||||
refresh();
|
||||
}
|
||||
} else {
|
||||
memmove(buf + pos + 1, buf + pos, len - pos);
|
||||
buf[pos++] = c;
|
||||
buf[++len] = '\0';
|
||||
memmove(gbl_buf + gbl_pos + 1, gbl_buf + gbl_pos, gbl_len - gbl_pos);
|
||||
gbl_buf[gbl_pos++] = c;
|
||||
gbl_buf[++gbl_len] = '\0';
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
@ -239,21 +245,21 @@ static int insert(char c) {
|
||||
}
|
||||
|
||||
static void historymove(int delta) {
|
||||
if (history_count > 1) {
|
||||
free(history[historyi]);
|
||||
history[historyi] = sdup(buf);
|
||||
if (gbl_history_count > 1) {
|
||||
free(gbl_history[gbl_historyi]);
|
||||
gbl_history[gbl_historyi] = sdup(gbl_buf);
|
||||
|
||||
historyi += delta;
|
||||
if (historyi < 0) {
|
||||
historyi = 0;
|
||||
gbl_historyi += delta;
|
||||
if (gbl_historyi < 0) {
|
||||
gbl_historyi = 0;
|
||||
return;
|
||||
} else if (historyi >= history_count) {
|
||||
historyi = history_count - 1;
|
||||
} else if (gbl_historyi >= gbl_history_count) {
|
||||
gbl_historyi = gbl_history_count - 1;
|
||||
return;
|
||||
}
|
||||
strncpy(buf, history[historyi], JANET_LINE_MAX - 1);
|
||||
pos = len = strlen(buf);
|
||||
buf[len] = '\0';
|
||||
strncpy(gbl_buf, gbl_history[gbl_historyi], JANET_LINE_MAX - 1);
|
||||
gbl_pos = gbl_len = strlen(gbl_buf);
|
||||
gbl_buf[gbl_len] = '\0';
|
||||
|
||||
refresh();
|
||||
}
|
||||
@ -261,62 +267,62 @@ static void historymove(int delta) {
|
||||
|
||||
static void addhistory() {
|
||||
int i, len;
|
||||
char *newline = sdup(buf);
|
||||
char *newline = sdup(gbl_buf);
|
||||
if (!newline) return;
|
||||
len = history_count;
|
||||
len = gbl_history_count;
|
||||
if (len < JANET_HISTORY_MAX) {
|
||||
history[history_count++] = newline;
|
||||
gbl_history[gbl_history_count++] = newline;
|
||||
len++;
|
||||
} else {
|
||||
free(history[JANET_HISTORY_MAX - 1]);
|
||||
free(gbl_history[JANET_HISTORY_MAX - 1]);
|
||||
}
|
||||
for (i = len - 1; i > 0; i--) {
|
||||
history[i] = history[i - 1];
|
||||
gbl_history[i] = gbl_history[i - 1];
|
||||
}
|
||||
history[0] = newline;
|
||||
gbl_history[0] = newline;
|
||||
}
|
||||
|
||||
static void replacehistory() {
|
||||
char *newline = sdup(buf);
|
||||
char *newline = sdup(gbl_buf);
|
||||
if (!newline) return;
|
||||
free(history[0]);
|
||||
history[0] = newline;
|
||||
free(gbl_history[0]);
|
||||
gbl_history[0] = newline;
|
||||
}
|
||||
|
||||
static void kleft() {
|
||||
if (pos > 0) {
|
||||
pos--;
|
||||
if (gbl_pos > 0) {
|
||||
gbl_pos--;
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
|
||||
static void kright() {
|
||||
if (pos != len) {
|
||||
pos++;
|
||||
if (gbl_pos != gbl_len) {
|
||||
gbl_pos++;
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
|
||||
static void kbackspace() {
|
||||
if (pos > 0) {
|
||||
memmove(buf + pos - 1, buf + pos, len - pos);
|
||||
pos--;
|
||||
buf[--len] = '\0';
|
||||
if (gbl_pos > 0) {
|
||||
memmove(gbl_buf + gbl_pos - 1, gbl_buf + gbl_pos, gbl_len - gbl_pos);
|
||||
gbl_pos--;
|
||||
gbl_buf[--gbl_len] = '\0';
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
|
||||
static int line() {
|
||||
cols = getcols();
|
||||
plen = 0;
|
||||
len = 0;
|
||||
pos = 0;
|
||||
while (prompt[plen]) plen++;
|
||||
buf[0] = '\0';
|
||||
gbl_cols = getcols();
|
||||
gbl_plen = 0;
|
||||
gbl_len = 0;
|
||||
gbl_pos = 0;
|
||||
while (gbl_prompt[gbl_plen]) gbl_plen++;
|
||||
gbl_buf[0] = '\0';
|
||||
|
||||
addhistory();
|
||||
|
||||
if (write(STDOUT_FILENO, prompt, plen) == -1) return -1;
|
||||
if (write(STDOUT_FILENO, gbl_prompt, gbl_plen) == -1) return -1;
|
||||
for (;;) {
|
||||
char c;
|
||||
int nread;
|
||||
@ -337,7 +343,7 @@ static int line() {
|
||||
return 0;
|
||||
case 3: /* ctrl-c */
|
||||
errno = EAGAIN;
|
||||
sigint_flag = 1;
|
||||
gbl_sigint_flag = 1;
|
||||
return -1;
|
||||
case 127: /* backspace */
|
||||
case 8: /* ctrl-h */
|
||||
@ -352,8 +358,8 @@ static int line() {
|
||||
kright();
|
||||
break;
|
||||
case 21:
|
||||
buf[0] = '\0';
|
||||
pos = len = 0;
|
||||
gbl_buf[0] = '\0';
|
||||
gbl_pos = gbl_len = 0;
|
||||
refresh();
|
||||
break;
|
||||
case 26: /* ctrl-z */
|
||||
@ -399,11 +405,11 @@ static int line() {
|
||||
kleft();
|
||||
break;
|
||||
case 'H':
|
||||
pos = 0;
|
||||
gbl_pos = 0;
|
||||
refresh();
|
||||
break;
|
||||
case 'F':
|
||||
pos = len;
|
||||
gbl_pos = gbl_len;
|
||||
refresh();
|
||||
break;
|
||||
}
|
||||
@ -413,11 +419,11 @@ static int line() {
|
||||
default:
|
||||
break;
|
||||
case 'H':
|
||||
pos = 0;
|
||||
gbl_pos = 0;
|
||||
refresh();
|
||||
break;
|
||||
case 'F':
|
||||
pos = len;
|
||||
gbl_pos = gbl_len;
|
||||
refresh();
|
||||
break;
|
||||
}
|
||||
@ -435,9 +441,9 @@ void janet_line_init() {
|
||||
void janet_line_deinit() {
|
||||
int i;
|
||||
norawmode();
|
||||
for (i = 0; i < history_count; i++)
|
||||
free(history[i]);
|
||||
historyi = 0;
|
||||
for (i = 0; i < gbl_history_count; i++)
|
||||
free(gbl_history[i]);
|
||||
gbl_historyi = 0;
|
||||
}
|
||||
|
||||
static int checktermsupport() {
|
||||
@ -450,9 +456,9 @@ static int checktermsupport() {
|
||||
}
|
||||
|
||||
void janet_line_get(const char *p, JanetBuffer *buffer) {
|
||||
prompt = p;
|
||||
gbl_prompt = p;
|
||||
buffer->count = 0;
|
||||
historyi = 0;
|
||||
gbl_historyi = 0;
|
||||
FILE *out = janet_dynfile("out", stdout);
|
||||
if (!isatty(STDIN_FILENO) || !checktermsupport()) {
|
||||
simpleline(buffer);
|
||||
@ -464,7 +470,7 @@ void janet_line_get(const char *p, JanetBuffer *buffer) {
|
||||
}
|
||||
if (line()) {
|
||||
norawmode();
|
||||
if (sigint_flag) {
|
||||
if (gbl_sigint_flag) {
|
||||
raise(SIGINT);
|
||||
} else {
|
||||
fputc('\n', out);
|
||||
@ -473,10 +479,10 @@ void janet_line_get(const char *p, JanetBuffer *buffer) {
|
||||
}
|
||||
norawmode();
|
||||
fputc('\n', out);
|
||||
janet_buffer_ensure(buffer, len + 1, 2);
|
||||
memcpy(buffer->data, buf, len);
|
||||
buffer->data[len] = '\n';
|
||||
buffer->count = len + 1;
|
||||
janet_buffer_ensure(buffer, gbl_len + 1, 2);
|
||||
memcpy(buffer->data, gbl_buf, gbl_len);
|
||||
buffer->data[gbl_len] = '\n';
|
||||
buffer->count = gbl_len + 1;
|
||||
replacehistory();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user