Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
path: root/source/extern/lua/lobject.c
diff options
context:
space:
mode:
authorKae <80987908+Novaenia@users.noreply.github.com>2025-01-05 15:16:15 +1100
committerKae <80987908+Novaenia@users.noreply.github.com>2025-01-05 15:16:15 +1100
commit9bc12f5f97f6774e6eeeb3ef577e026cc8d03357 (patch)
tree7b2909e6869cf1dff081e114e9693c8736b1480e /source/extern/lua/lobject.c
parent41f0b9001f60c59691ec04d937e6a9ef424794f1 (diff)
Lua 5.3.6
Diffstat (limited to 'source/extern/lua/lobject.c')
-rw-r--r--source/extern/lua/lobject.c113
1 files changed, 78 insertions, 35 deletions
diff --git a/source/extern/lua/lobject.c b/source/extern/lua/lobject.c
index 6c53b98..355bf58 100644
--- a/source/extern/lua/lobject.c
+++ b/source/extern/lua/lobject.c
@@ -1,5 +1,5 @@
/*
-** $Id: lobject.c,v 2.104 2015/04/11 18:30:08 roberto Exp $
+** $Id: lobject.c,v 2.113.1.1 2017/04/19 17:29:57 roberto Exp $
** Some generic functions over Lua objects
** See Copyright Notice in lua.h
*/
@@ -55,9 +55,7 @@ int luaO_int2fb (unsigned int x) {
/* converts back */
int luaO_fb2int (int x) {
- int e = (x >> 3) & 0x1f;
- if (e == 0) return x;
- else return ((x & 7) + 8) << (e - 1);
+ return (x < 8) ? x : ((x & 7) + 8) << ((x >> 3) - 1);
}
@@ -245,20 +243,59 @@ static lua_Number lua_strx2number (const char *s, char **endptr) {
/* }====================================================== */
-static const char *l_str2d (const char *s, lua_Number *result) {
+/* maximum length of a numeral */
+#if !defined (L_MAXLENNUM)
+#define L_MAXLENNUM 200
+#endif
+
+static const char *l_str2dloc (const char *s, lua_Number *result, int mode) {
char *endptr;
- if (strpbrk(s, "nN")) /* reject 'inf' and 'nan' */
+ *result = (mode == 'x') ? lua_strx2number(s, &endptr) /* try to convert */
+ : lua_str2number(s, &endptr);
+ if (endptr == s) return NULL; /* nothing recognized? */
+ while (lisspace(cast_uchar(*endptr))) endptr++; /* skip trailing spaces */
+ return (*endptr == '\0') ? endptr : NULL; /* OK if no trailing characters */
+}
+
+
+/*
+** Convert string 's' to a Lua number (put in 'result'). Return NULL
+** on fail or the address of the ending '\0' on success.
+** 'pmode' points to (and 'mode' contains) special things in the string:
+** - 'x'/'X' means an hexadecimal numeral
+** - 'n'/'N' means 'inf' or 'nan' (which should be rejected)
+** - '.' just optimizes the search for the common case (nothing special)
+** This function accepts both the current locale or a dot as the radix
+** mark. If the conversion fails, it may mean number has a dot but
+** locale accepts something else. In that case, the code copies 's'
+** to a buffer (because 's' is read-only), changes the dot to the
+** current locale radix mark, and tries to convert again.
+*/
+static const char *l_str2d (const char *s, lua_Number *result) {
+ const char *endptr;
+ const char *pmode = strpbrk(s, ".xXnN");
+ int mode = pmode ? ltolower(cast_uchar(*pmode)) : 0;
+ if (mode == 'n') /* reject 'inf' and 'nan' */
return NULL;
- else if (strpbrk(s, "xX")) /* hex? */
- *result = lua_strx2number(s, &endptr);
- else
- *result = lua_str2number(s, &endptr);
- if (endptr == s) return NULL; /* nothing recognized */
- while (lisspace(cast_uchar(*endptr))) endptr++;
- return (*endptr == '\0' ? endptr : NULL); /* OK if no trailing characters */
+ endptr = l_str2dloc(s, result, mode); /* try to convert */
+ if (endptr == NULL) { /* failed? may be a different locale */
+ char buff[L_MAXLENNUM + 1];
+ const char *pdot = strchr(s, '.');
+ if (strlen(s) > L_MAXLENNUM || pdot == NULL)
+ return NULL; /* string too long or no dot; fail */
+ strcpy(buff, s); /* copy string to buffer */
+ buff[pdot - s] = lua_getlocaledecpoint(); /* correct decimal point */
+ endptr = l_str2dloc(buff, result, mode); /* try again */
+ if (endptr != NULL)
+ endptr = s + (endptr - buff); /* make relative to 's' */
+ }
+ return endptr;
}
+#define MAXBY10 cast(lua_Unsigned, LUA_MAXINTEGER / 10)
+#define MAXLASTD cast_int(LUA_MAXINTEGER % 10)
+
static const char *l_str2int (const char *s, lua_Integer *result) {
lua_Unsigned a = 0;
int empty = 1;
@@ -275,7 +312,10 @@ static const char *l_str2int (const char *s, lua_Integer *result) {
}
else { /* decimal */
for (; lisdigit(cast_uchar(*s)); s++) {
- a = a * 10 + *s - '0';
+ int d = *s - '0';
+ if (a >= MAXBY10 && (a > MAXBY10 || d > MAXLASTD + neg)) /* overflow? */
+ return NULL; /* do not accept it (as integer) */
+ a = a * 10 + d;
empty = 0;
}
}
@@ -333,9 +373,9 @@ void luaO_tostring (lua_State *L, StkId obj) {
size_t len;
lua_assert(ttisnumber(obj));
if (ttisinteger(obj))
- len = lua_integer2str(buff, ivalue(obj));
+ len = lua_integer2str(buff, sizeof(buff), ivalue(obj));
else {
- len = lua_number2str(buff, fltvalue(obj));
+ len = lua_number2str(buff, sizeof(buff), fltvalue(obj));
#if !defined(LUA_COMPAT_FLOATSTRING)
if (buff[strspn(buff, "-0123456789")] == '\0') { /* looks like an int? */
buff[len++] = lua_getlocaledecpoint();
@@ -348,27 +388,29 @@ void luaO_tostring (lua_State *L, StkId obj) {
static void pushstr (lua_State *L, const char *str, size_t l) {
- setsvalue2s(L, L->top++, luaS_newlstr(L, str, l));
+ setsvalue2s(L, L->top, luaS_newlstr(L, str, l));
+ luaD_inctop(L);
}
-/* this function handles only '%d', '%c', '%f', '%p', and '%s'
- conventional formats, plus Lua-specific '%I' and '%U' */
+/*
+** this function handles only '%d', '%c', '%f', '%p', and '%s'
+ conventional formats, plus Lua-specific '%I' and '%U'
+*/
const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
int n = 0;
for (;;) {
const char *e = strchr(fmt, '%');
if (e == NULL) break;
- luaD_checkstack(L, 2); /* fmt + item */
pushstr(L, fmt, e - fmt);
switch (*(e+1)) {
- case 's': {
+ case 's': { /* zero-terminated string */
const char *s = va_arg(argp, char *);
if (s == NULL) s = "(null)";
pushstr(L, s, strlen(s));
break;
}
- case 'c': {
+ case 'c': { /* an 'int' as a character */
char buff = cast(char, va_arg(argp, int));
if (lisprint(cast_uchar(buff)))
pushstr(L, &buff, 1);
@@ -376,28 +418,29 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
luaO_pushfstring(L, "<\\%d>", cast_uchar(buff));
break;
}
- case 'd': {
- setivalue(L->top++, va_arg(argp, int));
- luaO_tostring(L, L->top - 1);
- break;
+ case 'd': { /* an 'int' */
+ setivalue(L->top, va_arg(argp, int));
+ goto top2str;
}
- case 'I': {
- setivalue(L->top++, cast(lua_Integer, va_arg(argp, l_uacInt)));
- luaO_tostring(L, L->top - 1);
- break;
+ case 'I': { /* a 'lua_Integer' */
+ setivalue(L->top, cast(lua_Integer, va_arg(argp, l_uacInt)));
+ goto top2str;
}
- case 'f': {
- setfltvalue(L->top++, cast_num(va_arg(argp, l_uacNumber)));
+ case 'f': { /* a 'lua_Number' */
+ setfltvalue(L->top, cast_num(va_arg(argp, l_uacNumber)));
+ top2str: /* convert the top element to a string */
+ luaD_inctop(L);
luaO_tostring(L, L->top - 1);
break;
}
- case 'p': {
+ case 'p': { /* a pointer */
char buff[4*sizeof(void *) + 8]; /* should be enough space for a '%p' */
- int l = sprintf(buff, "%p", va_arg(argp, void *));
+ void *p = va_arg(argp, void *);
+ int l = lua_pointer2str(buff, sizeof(buff), p);
pushstr(L, buff, l);
break;
}
- case 'U': {
+ case 'U': { /* an 'int' as a UTF-8 sequence */
char buff[UTF8BUFFSZ];
int l = luaO_utf8esc(buff, cast(long, va_arg(argp, long)));
pushstr(L, buff + UTF8BUFFSZ - l, l);