mirror of https://github.com/rusefi/lua.git
bug: "format" does not check size of format item (such as "%00000...00000d").
This commit is contained in:
parent
8278468041
commit
b94110a68f
3
bugs
3
bugs
|
@ -58,3 +58,6 @@ Fri Dec 18 11:22:55 EDT 1998
|
||||||
>> "tonumber" goes crazy with negative numbers in other bases (not 10),
|
>> "tonumber" goes crazy with negative numbers in other bases (not 10),
|
||||||
because "strtol" returns long, not unsigned long.
|
because "strtol" returns long, not unsigned long.
|
||||||
|
|
||||||
|
** lstrlib.c
|
||||||
|
Mon Jan 4 10:41:40 EDT 1999
|
||||||
|
>> "format" does not check size of format item (such as "%00000...00000d").
|
||||||
|
|
72
lstrlib.c
72
lstrlib.c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: lstrlib.c,v 1.21 1998/12/01 18:41:25 roberto Exp roberto $
|
** $Id: lstrlib.c,v 1.22 1998/12/28 13:44:54 roberto Exp $
|
||||||
** Standard library for strings and pattern-matching
|
** Standard library for strings and pattern-matching
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -67,8 +67,7 @@ static void str_lower (void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void str_upper (void)
|
static void str_upper (void) {
|
||||||
{
|
|
||||||
long l;
|
long l;
|
||||||
int i;
|
int i;
|
||||||
char *s = luaL_check_lstr(1, &l);
|
char *s = luaL_check_lstr(1, &l);
|
||||||
|
@ -90,8 +89,7 @@ static void str_rep (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void str_byte (void)
|
static void str_byte (void) {
|
||||||
{
|
|
||||||
long l;
|
long l;
|
||||||
char *s = luaL_check_lstr(1, &l);
|
char *s = luaL_check_lstr(1, &l);
|
||||||
long pos = posrelat(luaL_opt_long(2, 1), l);
|
long pos = posrelat(luaL_opt_long(2, 1), l);
|
||||||
|
@ -99,6 +97,7 @@ static void str_byte (void)
|
||||||
lua_pushnumber((unsigned char)s[pos-1]);
|
lua_pushnumber((unsigned char)s[pos-1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void str_char (void) {
|
static void str_char (void) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
luaL_resetbuffer();
|
luaL_resetbuffer();
|
||||||
|
@ -111,8 +110,9 @@ static void str_char (void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** =======================================================
|
** {======================================================
|
||||||
** PATTERN MATCHING
|
** PATTERN MATCHING
|
||||||
** =======================================================
|
** =======================================================
|
||||||
*/
|
*/
|
||||||
|
@ -120,8 +120,8 @@ static void str_char (void) {
|
||||||
#define MAX_CAPT 9
|
#define MAX_CAPT 9
|
||||||
|
|
||||||
struct Capture {
|
struct Capture {
|
||||||
int level; /* total number of captures (finished or unfinished) */
|
|
||||||
char *src_end; /* end ('\0') of source string */
|
char *src_end; /* end ('\0') of source string */
|
||||||
|
int level; /* total number of captures (finished or unfinished) */
|
||||||
struct {
|
struct {
|
||||||
char *init;
|
char *init;
|
||||||
int len; /* -1 signals unfinished capture */
|
int len; /* -1 signals unfinished capture */
|
||||||
|
@ -133,8 +133,7 @@ struct Capture {
|
||||||
#define SPECIALS "^$*?.([%-"
|
#define SPECIALS "^$*?.([%-"
|
||||||
|
|
||||||
|
|
||||||
static void push_captures (struct Capture *cap)
|
static void push_captures (struct Capture *cap) {
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
for (i=0; i<cap->level; i++) {
|
for (i=0; i<cap->level; i++) {
|
||||||
int l = cap->capture[i].len;
|
int l = cap->capture[i].len;
|
||||||
|
@ -144,8 +143,7 @@ static void push_captures (struct Capture *cap)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int check_cap (int l, struct Capture *cap)
|
static int check_cap (int l, struct Capture *cap) {
|
||||||
{
|
|
||||||
l -= '1';
|
l -= '1';
|
||||||
if (!(0 <= l && l < cap->level && cap->capture[l].len != -1))
|
if (!(0 <= l && l < cap->level && cap->capture[l].len != -1))
|
||||||
lua_error("invalid capture index");
|
lua_error("invalid capture index");
|
||||||
|
@ -153,8 +151,7 @@ static int check_cap (int l, struct Capture *cap)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int capture_to_close (struct Capture *cap)
|
static int capture_to_close (struct Capture *cap) {
|
||||||
{
|
|
||||||
int level = cap->level;
|
int level = cap->level;
|
||||||
for (level--; level>=0; level--)
|
for (level--; level>=0; level--)
|
||||||
if (cap->capture[level].len == -1) return level;
|
if (cap->capture[level].len == -1) return level;
|
||||||
|
@ -163,14 +160,12 @@ static int capture_to_close (struct Capture *cap)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static char *bracket_end (char *p)
|
static char *bracket_end (char *p) {
|
||||||
{
|
|
||||||
return (*p == 0) ? NULL : strchr((*p=='^') ? p+2 : p+1, ']');
|
return (*p == 0) ? NULL : strchr((*p=='^') ? p+2 : p+1, ']');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int matchclass (int c, int cl)
|
static int matchclass (int c, int cl) {
|
||||||
{
|
|
||||||
int res;
|
int res;
|
||||||
switch (tolower(cl)) {
|
switch (tolower(cl)) {
|
||||||
case 'a' : res = isalpha(c); break;
|
case 'a' : res = isalpha(c); break;
|
||||||
|
@ -181,15 +176,15 @@ static int matchclass (int c, int cl)
|
||||||
case 's' : res = isspace(c); break;
|
case 's' : res = isspace(c); break;
|
||||||
case 'u' : res = isupper(c); break;
|
case 'u' : res = isupper(c); break;
|
||||||
case 'w' : res = isalnum(c); break;
|
case 'w' : res = isalnum(c); break;
|
||||||
|
case 'x' : res = isxdigit(c); break;
|
||||||
case 'z' : res = (c == '\0'); break;
|
case 'z' : res = (c == '\0'); break;
|
||||||
default: return (cl == c);
|
default: return (cl == c);
|
||||||
}
|
}
|
||||||
return (islower((unsigned char)cl) ? res : !res);
|
return (islower(cl) ? res : !res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int luaI_singlematch (int c, char *p, char **ep)
|
int luaI_singlematch (int c, char *p, char **ep) {
|
||||||
{
|
|
||||||
switch (*p) {
|
switch (*p) {
|
||||||
case '.': /* matches any char */
|
case '.': /* matches any char */
|
||||||
*ep = p+1;
|
*ep = p+1;
|
||||||
|
@ -228,8 +223,7 @@ int luaI_singlematch (int c, char *p, char **ep)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static char *matchbalance (char *s, int b, int e, struct Capture *cap)
|
static char *matchbalance (char *s, int b, int e, struct Capture *cap) {
|
||||||
{
|
|
||||||
if (*s != b) return NULL;
|
if (*s != b) return NULL;
|
||||||
else {
|
else {
|
||||||
int cont = 1;
|
int cont = 1;
|
||||||
|
@ -244,8 +238,7 @@ static char *matchbalance (char *s, int b, int e, struct Capture *cap)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static char *matchitem (char *s, char *p, struct Capture *cap, char **ep)
|
static char *matchitem (char *s, char *p, struct Capture *cap, char **ep) {
|
||||||
{
|
|
||||||
if (*p == ESC) {
|
if (*p == ESC) {
|
||||||
p++;
|
p++;
|
||||||
if (isdigit((unsigned char)*p)) { /* capture */
|
if (isdigit((unsigned char)*p)) { /* capture */
|
||||||
|
@ -265,14 +258,13 @@ static char *matchitem (char *s, char *p, struct Capture *cap, char **ep)
|
||||||
}
|
}
|
||||||
else p--; /* and go through */
|
else p--; /* and go through */
|
||||||
}
|
}
|
||||||
/* "luaI_singlematch" sets "ep" (so must be called even when *s == 0) */
|
/* "luaI_singlematch" sets "ep" (so must be called even at the end of "s" */
|
||||||
return (luaI_singlematch((unsigned char)*s, p, ep) && s<cap->src_end) ?
|
return (luaI_singlematch((unsigned char)*s, p, ep) && s<cap->src_end) ?
|
||||||
s+1 : NULL;
|
s+1 : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static char *match (char *s, char *p, struct Capture *cap)
|
static char *match (char *s, char *p, struct Capture *cap) {
|
||||||
{
|
|
||||||
init: /* using goto's to optimize tail recursion */
|
init: /* using goto's to optimize tail recursion */
|
||||||
switch (*p) {
|
switch (*p) {
|
||||||
case '(': { /* start capture */
|
case '(': { /* start capture */
|
||||||
|
@ -298,7 +290,7 @@ static char *match (char *s, char *p, struct Capture *cap)
|
||||||
return s;
|
return s;
|
||||||
/* else go through */
|
/* else go through */
|
||||||
default: { /* it is a pattern item */
|
default: { /* it is a pattern item */
|
||||||
char *ep; /* get what is next */
|
char *ep; /* will point to what is next */
|
||||||
char *s1 = matchitem(s, p, cap, &ep);
|
char *s1 = matchitem(s, p, cap, &ep);
|
||||||
switch (*ep) {
|
switch (*ep) {
|
||||||
case '*': { /* repetition */
|
case '*': { /* repetition */
|
||||||
|
@ -333,8 +325,7 @@ static char *match (char *s, char *p, struct Capture *cap)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void str_find (void)
|
static void str_find (void) {
|
||||||
{
|
|
||||||
long l;
|
long l;
|
||||||
char *s = luaL_check_lstr(1, &l);
|
char *s = luaL_check_lstr(1, &l);
|
||||||
char *p = luaL_check_string(2);
|
char *p = luaL_check_string(2);
|
||||||
|
@ -369,8 +360,7 @@ static void str_find (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void add_s (lua_Object newp, struct Capture *cap)
|
static void add_s (lua_Object newp, struct Capture *cap) {
|
||||||
{
|
|
||||||
if (lua_isstring(newp)) {
|
if (lua_isstring(newp)) {
|
||||||
char *news = lua_getstring(newp);
|
char *news = lua_getstring(newp);
|
||||||
int l = lua_strlen(newp);
|
int l = lua_strlen(newp);
|
||||||
|
@ -412,8 +402,7 @@ static void add_s (lua_Object newp, struct Capture *cap)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void str_gsub (void)
|
static void str_gsub (void) {
|
||||||
{
|
|
||||||
long srcl;
|
long srcl;
|
||||||
char *src = luaL_check_lstr(1, &srcl);
|
char *src = luaL_check_lstr(1, &srcl);
|
||||||
char *p = luaL_check_string(2);
|
char *p = luaL_check_string(2);
|
||||||
|
@ -446,6 +435,8 @@ static void str_gsub (void)
|
||||||
lua_pushnumber(n); /* number of substitutions */
|
lua_pushnumber(n); /* number of substitutions */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* }====================================================== */
|
||||||
|
|
||||||
|
|
||||||
static void luaI_addquoted (int arg) {
|
static void luaI_addquoted (int arg) {
|
||||||
long l;
|
long l;
|
||||||
|
@ -465,10 +456,10 @@ static void luaI_addquoted (int arg) {
|
||||||
luaL_addchar('"');
|
luaL_addchar('"');
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAX_FORMAT 200
|
/* maximum size of each format specification (such as '%-099.99d') */
|
||||||
|
#define MAX_FORMAT 20
|
||||||
|
|
||||||
static void str_format (void)
|
static void str_format (void) {
|
||||||
{
|
|
||||||
int arg = 1;
|
int arg = 1;
|
||||||
char *strfrmt = luaL_check_string(arg);
|
char *strfrmt = luaL_check_string(arg);
|
||||||
struct Capture cap;
|
struct Capture cap;
|
||||||
|
@ -491,11 +482,14 @@ static void str_format (void)
|
||||||
}
|
}
|
||||||
arg++;
|
arg++;
|
||||||
strfrmt = match(initf, "[-+ #0]*(%d*)%.?(%d*)", &cap);
|
strfrmt = match(initf, "[-+ #0]*(%d*)%.?(%d*)", &cap);
|
||||||
if (cap.capture[0].len > 2 || cap.capture[1].len > 2) /* < 100? */
|
if (cap.capture[0].len > 2 || cap.capture[1].len > 2 || /* < 100? */
|
||||||
|
strfrmt-initf > MAX_FORMAT-2)
|
||||||
lua_error("invalid format (width or precision too long)");
|
lua_error("invalid format (width or precision too long)");
|
||||||
strncpy(form+1, initf, strfrmt-initf+1); /* +1 to include conversion */
|
strncpy(form+1, initf, strfrmt-initf+1); /* +1 to include conversion */
|
||||||
form[strfrmt-initf+2] = 0;
|
form[strfrmt-initf+2] = 0;
|
||||||
buff = luaL_openspace(1000); /* to store the formatted value */
|
/* to store the formatted value
|
||||||
|
(450 > size of format('%99.99f', -1e308) */
|
||||||
|
buff = luaL_openspace(450);
|
||||||
switch (*strfrmt++) {
|
switch (*strfrmt++) {
|
||||||
case 'q':
|
case 'q':
|
||||||
luaI_addquoted(arg);
|
luaI_addquoted(arg);
|
||||||
|
|
Loading…
Reference in New Issue