diff options
| author | Li Jin <dragon-fly@qq.com> | 2021-11-02 11:17:58 +0800 |
|---|---|---|
| committer | Li Jin <dragon-fly@qq.com> | 2021-11-02 11:17:58 +0800 |
| commit | 827c3736f357e09168fc108e8e740c6425d37d9b (patch) | |
| tree | 259f977bf7f4ebe0e397fe5e1b74e7fbb1b75e8e /src/3rdParty/lua/lstrlib.c | |
| parent | aed806476fe50899c0f01750175531ac41267b9d (diff) | |
| download | yuescript-827c3736f357e09168fc108e8e740c6425d37d9b.tar.gz yuescript-827c3736f357e09168fc108e8e740c6425d37d9b.tar.bz2 yuescript-827c3736f357e09168fc108e8e740c6425d37d9b.zip | |
fix a wrong code generating issue, update builtin Lua.
Diffstat (limited to 'src/3rdParty/lua/lstrlib.c')
| -rw-r--r-- | src/3rdParty/lua/lstrlib.c | 112 |
1 files changed, 86 insertions, 26 deletions
diff --git a/src/3rdParty/lua/lstrlib.c b/src/3rdParty/lua/lstrlib.c index 74501f7..0b4fdbb 100644 --- a/src/3rdParty/lua/lstrlib.c +++ b/src/3rdParty/lua/lstrlib.c | |||
| @@ -1090,13 +1090,31 @@ static int lua_number2strx (lua_State *L, char *buff, int sz, | |||
| 1090 | 1090 | ||
| 1091 | 1091 | ||
| 1092 | /* valid flags in a format specification */ | 1092 | /* valid flags in a format specification */ |
| 1093 | #if !defined(L_FMTFLAGS) | 1093 | #if !defined(L_FMTFLAGSF) |
| 1094 | #define L_FMTFLAGS "-+ #0" | 1094 | |
| 1095 | /* valid flags for a, A, e, E, f, F, g, and G conversions */ | ||
| 1096 | #define L_FMTFLAGSF "-+#0 " | ||
| 1097 | |||
| 1098 | /* valid flags for o, x, and X conversions */ | ||
| 1099 | #define L_FMTFLAGSX "-#0" | ||
| 1100 | |||
| 1101 | /* valid flags for d and i conversions */ | ||
| 1102 | #define L_FMTFLAGSI "-+0 " | ||
| 1103 | |||
| 1104 | /* valid flags for u conversions */ | ||
| 1105 | #define L_FMTFLAGSU "-0" | ||
| 1106 | |||
| 1107 | /* valid flags for c, p, and s conversions */ | ||
| 1108 | #define L_FMTFLAGSC "-" | ||
| 1109 | |||
| 1095 | #endif | 1110 | #endif |
| 1096 | 1111 | ||
| 1097 | 1112 | ||
| 1098 | /* | 1113 | /* |
| 1099 | ** maximum size of each format specification (such as "%-099.99d") | 1114 | ** Maximum size of each format specification (such as "%-099.99d"): |
| 1115 | ** Initial '%', flags (up to 5), width (2), period, precision (2), | ||
| 1116 | ** length modifier (8), conversion specifier, and final '\0', plus some | ||
| 1117 | ** extra. | ||
| 1100 | */ | 1118 | */ |
| 1101 | #define MAX_FORMAT 32 | 1119 | #define MAX_FORMAT 32 |
| 1102 | 1120 | ||
| @@ -1189,25 +1207,53 @@ static void addliteral (lua_State *L, luaL_Buffer *b, int arg) { | |||
| 1189 | } | 1207 | } |
| 1190 | 1208 | ||
| 1191 | 1209 | ||
| 1192 | static const char *scanformat (lua_State *L, const char *strfrmt, char *form) { | 1210 | static const char *get2digits (const char *s) { |
| 1193 | const char *p = strfrmt; | 1211 | if (isdigit(uchar(*s))) { |
| 1194 | while (*p != '\0' && strchr(L_FMTFLAGS, *p) != NULL) p++; /* skip flags */ | 1212 | s++; |
| 1195 | if ((size_t)(p - strfrmt) >= sizeof(L_FMTFLAGS)/sizeof(char)) | 1213 | if (isdigit(uchar(*s))) s++; /* (2 digits at most) */ |
| 1196 | luaL_error(L, "invalid format (repeated flags)"); | 1214 | } |
| 1197 | if (isdigit(uchar(*p))) p++; /* skip width */ | 1215 | return s; |
| 1198 | if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ | 1216 | } |
| 1199 | if (*p == '.') { | 1217 | |
| 1200 | p++; | 1218 | |
| 1201 | if (isdigit(uchar(*p))) p++; /* skip precision */ | 1219 | /* |
| 1202 | if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ | 1220 | ** Check whether a conversion specification is valid. When called, |
| 1221 | ** first character in 'form' must be '%' and last character must | ||
| 1222 | ** be a valid conversion specifier. 'flags' are the accepted flags; | ||
| 1223 | ** 'precision' signals whether to accept a precision. | ||
| 1224 | */ | ||
| 1225 | static void checkformat (lua_State *L, const char *form, const char *flags, | ||
| 1226 | int precision) { | ||
| 1227 | const char *spec = form + 1; /* skip '%' */ | ||
| 1228 | spec += strspn(spec, flags); /* skip flags */ | ||
| 1229 | if (*spec != '0') { /* a width cannot start with '0' */ | ||
| 1230 | spec = get2digits(spec); /* skip width */ | ||
| 1231 | if (*spec == '.' && precision) { | ||
| 1232 | spec++; | ||
| 1233 | spec = get2digits(spec); /* skip precision */ | ||
| 1234 | } | ||
| 1203 | } | 1235 | } |
| 1204 | if (isdigit(uchar(*p))) | 1236 | if (!isalpha(uchar(*spec))) /* did not go to the end? */ |
| 1205 | luaL_error(L, "invalid format (width or precision too long)"); | 1237 | luaL_error(L, "invalid conversion specification: '%s'", form); |
| 1238 | } | ||
| 1239 | |||
| 1240 | |||
| 1241 | /* | ||
| 1242 | ** Get a conversion specification and copy it to 'form'. | ||
| 1243 | ** Return the address of its last character. | ||
| 1244 | */ | ||
| 1245 | static const char *getformat (lua_State *L, const char *strfrmt, | ||
| 1246 | char *form) { | ||
| 1247 | /* spans flags, width, and precision ('0' is included as a flag) */ | ||
| 1248 | size_t len = strspn(strfrmt, L_FMTFLAGSF "123456789."); | ||
| 1249 | len++; /* adds following character (should be the specifier) */ | ||
| 1250 | /* still needs space for '%', '\0', plus a length modifier */ | ||
| 1251 | if (len >= MAX_FORMAT - 10) | ||
| 1252 | luaL_error(L, "invalid format (too long)"); | ||
| 1206 | *(form++) = '%'; | 1253 | *(form++) = '%'; |
| 1207 | memcpy(form, strfrmt, ((p - strfrmt) + 1) * sizeof(char)); | 1254 | memcpy(form, strfrmt, len * sizeof(char)); |
| 1208 | form += (p - strfrmt) + 1; | 1255 | *(form + len) = '\0'; |
| 1209 | *form = '\0'; | 1256 | return strfrmt + len - 1; |
| 1210 | return p; | ||
| 1211 | } | 1257 | } |
| 1212 | 1258 | ||
| 1213 | 1259 | ||
| @@ -1230,6 +1276,7 @@ static int str_format (lua_State *L) { | |||
| 1230 | size_t sfl; | 1276 | size_t sfl; |
| 1231 | const char *strfrmt = luaL_checklstring(L, arg, &sfl); | 1277 | const char *strfrmt = luaL_checklstring(L, arg, &sfl); |
| 1232 | const char *strfrmt_end = strfrmt+sfl; | 1278 | const char *strfrmt_end = strfrmt+sfl; |
| 1279 | const char *flags; | ||
| 1233 | luaL_Buffer b; | 1280 | luaL_Buffer b; |
| 1234 | luaL_buffinit(L, &b); | 1281 | luaL_buffinit(L, &b); |
| 1235 | while (strfrmt < strfrmt_end) { | 1282 | while (strfrmt < strfrmt_end) { |
| @@ -1239,25 +1286,35 @@ static int str_format (lua_State *L) { | |||
| 1239 | luaL_addchar(&b, *strfrmt++); /* %% */ | 1286 | luaL_addchar(&b, *strfrmt++); /* %% */ |
| 1240 | else { /* format item */ | 1287 | else { /* format item */ |
| 1241 | char form[MAX_FORMAT]; /* to store the format ('%...') */ | 1288 | char form[MAX_FORMAT]; /* to store the format ('%...') */ |
| 1242 | int maxitem = MAX_ITEM; | 1289 | int maxitem = MAX_ITEM; /* maximum length for the result */ |
| 1243 | char *buff = luaL_prepbuffsize(&b, maxitem); /* to put formatted item */ | 1290 | char *buff = luaL_prepbuffsize(&b, maxitem); /* to put result */ |
| 1244 | int nb = 0; /* number of bytes in added item */ | 1291 | int nb = 0; /* number of bytes in result */ |
| 1245 | if (++arg > top) | 1292 | if (++arg > top) |
| 1246 | return luaL_argerror(L, arg, "no value"); | 1293 | return luaL_argerror(L, arg, "no value"); |
| 1247 | strfrmt = scanformat(L, strfrmt, form); | 1294 | strfrmt = getformat(L, strfrmt, form); |
| 1248 | switch (*strfrmt++) { | 1295 | switch (*strfrmt++) { |
| 1249 | case 'c': { | 1296 | case 'c': { |
| 1297 | checkformat(L, form, L_FMTFLAGSC, 0); | ||
| 1250 | nb = l_sprintf(buff, maxitem, form, (int)luaL_checkinteger(L, arg)); | 1298 | nb = l_sprintf(buff, maxitem, form, (int)luaL_checkinteger(L, arg)); |
| 1251 | break; | 1299 | break; |
| 1252 | } | 1300 | } |
| 1253 | case 'd': case 'i': | 1301 | case 'd': case 'i': |
| 1254 | case 'o': case 'u': case 'x': case 'X': { | 1302 | flags = L_FMTFLAGSI; |
| 1303 | goto intcase; | ||
| 1304 | case 'u': | ||
| 1305 | flags = L_FMTFLAGSU; | ||
| 1306 | goto intcase; | ||
| 1307 | case 'o': case 'x': case 'X': | ||
| 1308 | flags = L_FMTFLAGSX; | ||
| 1309 | intcase: { | ||
| 1255 | lua_Integer n = luaL_checkinteger(L, arg); | 1310 | lua_Integer n = luaL_checkinteger(L, arg); |
| 1311 | checkformat(L, form, flags, 1); | ||
| 1256 | addlenmod(form, LUA_INTEGER_FRMLEN); | 1312 | addlenmod(form, LUA_INTEGER_FRMLEN); |
| 1257 | nb = l_sprintf(buff, maxitem, form, (LUAI_UACINT)n); | 1313 | nb = l_sprintf(buff, maxitem, form, (LUAI_UACINT)n); |
| 1258 | break; | 1314 | break; |
| 1259 | } | 1315 | } |
| 1260 | case 'a': case 'A': | 1316 | case 'a': case 'A': |
| 1317 | checkformat(L, form, L_FMTFLAGSF, 1); | ||
| 1261 | addlenmod(form, LUA_NUMBER_FRMLEN); | 1318 | addlenmod(form, LUA_NUMBER_FRMLEN); |
| 1262 | nb = lua_number2strx(L, buff, maxitem, form, | 1319 | nb = lua_number2strx(L, buff, maxitem, form, |
| 1263 | luaL_checknumber(L, arg)); | 1320 | luaL_checknumber(L, arg)); |
| @@ -1268,12 +1325,14 @@ static int str_format (lua_State *L) { | |||
| 1268 | /* FALLTHROUGH */ | 1325 | /* FALLTHROUGH */ |
| 1269 | case 'e': case 'E': case 'g': case 'G': { | 1326 | case 'e': case 'E': case 'g': case 'G': { |
| 1270 | lua_Number n = luaL_checknumber(L, arg); | 1327 | lua_Number n = luaL_checknumber(L, arg); |
| 1328 | checkformat(L, form, L_FMTFLAGSF, 1); | ||
| 1271 | addlenmod(form, LUA_NUMBER_FRMLEN); | 1329 | addlenmod(form, LUA_NUMBER_FRMLEN); |
| 1272 | nb = l_sprintf(buff, maxitem, form, (LUAI_UACNUMBER)n); | 1330 | nb = l_sprintf(buff, maxitem, form, (LUAI_UACNUMBER)n); |
| 1273 | break; | 1331 | break; |
| 1274 | } | 1332 | } |
| 1275 | case 'p': { | 1333 | case 'p': { |
| 1276 | const void *p = lua_topointer(L, arg); | 1334 | const void *p = lua_topointer(L, arg); |
| 1335 | checkformat(L, form, L_FMTFLAGSC, 0); | ||
| 1277 | if (p == NULL) { /* avoid calling 'printf' with argument NULL */ | 1336 | if (p == NULL) { /* avoid calling 'printf' with argument NULL */ |
| 1278 | p = "(null)"; /* result */ | 1337 | p = "(null)"; /* result */ |
| 1279 | form[strlen(form) - 1] = 's'; /* format it as a string */ | 1338 | form[strlen(form) - 1] = 's'; /* format it as a string */ |
| @@ -1294,7 +1353,8 @@ static int str_format (lua_State *L) { | |||
| 1294 | luaL_addvalue(&b); /* keep entire string */ | 1353 | luaL_addvalue(&b); /* keep entire string */ |
| 1295 | else { | 1354 | else { |
| 1296 | luaL_argcheck(L, l == strlen(s), arg, "string contains zeros"); | 1355 | luaL_argcheck(L, l == strlen(s), arg, "string contains zeros"); |
| 1297 | if (!strchr(form, '.') && l >= 100) { | 1356 | checkformat(L, form, L_FMTFLAGSC, 1); |
| 1357 | if (strchr(form, '.') == NULL && l >= 100) { | ||
| 1298 | /* no precision and string is too long to be formatted */ | 1358 | /* no precision and string is too long to be formatted */ |
| 1299 | luaL_addvalue(&b); /* keep entire string */ | 1359 | luaL_addvalue(&b); /* keep entire string */ |
| 1300 | } | 1360 | } |
