summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
authorHaru <haru@dotalux.com>2020-05-10 20:35:59 +0200
committerGitHub <noreply@github.com>2020-05-10 20:35:59 +0200
commit0d66a7243aa6e129cddea4ca09c2616354c23ffa (patch)
tree56fe416e50f56c2265d72b920efd238538ac22ab /src/map
parent944d8489f1bcca93e6b2ff06a159084f064dce12 (diff)
parent66f9a2a1bc2fd509d13729ad6bc586a3b7ad2347 (diff)
downloadhercules-0d66a7243aa6e129cddea4ca09c2616354c23ffa.tar.gz
hercules-0d66a7243aa6e129cddea4ca09c2616354c23ffa.tar.bz2
hercules-0d66a7243aa6e129cddea4ca09c2616354c23ffa.tar.xz
hercules-0d66a7243aa6e129cddea4ca09c2616354c23ffa.zip
Merge pull request #2705 from Kenpachi2k13/string_var_size
Cap string variable value length and unify corresponding SQL columns size
Diffstat (limited to 'src/map')
-rw-r--r--src/map/atcommand.c8
-rw-r--r--src/map/clif.c2
-rw-r--r--src/map/intif.c14
-rw-r--r--src/map/mapreg_sql.c10
-rw-r--r--src/map/npc_chat.c3
-rw-r--r--src/map/script.c39
-rw-r--r--src/map/script.h1
7 files changed, 61 insertions, 16 deletions
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 3fe6c8581..54cc9e2c9 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -8916,13 +8916,17 @@ ACMD(accinfo)
/* [Ind] */
ACMD(set)
{
- char reg[SCRIPT_VARNAME_LENGTH+1], val[254];
+ char reg[SCRIPT_VARNAME_LENGTH + 1];
+ char val[SCRIPT_STRING_VAR_LENGTH + 1];
struct script_data* data;
int toset = 0;
bool is_str = false;
size_t len;
- if (!*message || (toset = sscanf(message, "%32s %253[^\n]", reg, val)) < 1) {
+ char format[20];
+ safesnprintf(format, sizeof(format), "%%%ds %%%d[^\\n]", SCRIPT_VARNAME_LENGTH, SCRIPT_STRING_VAR_LENGTH);
+
+ if (*message == '\0' || (toset = sscanf(message, format, reg, val)) < 1) {
clif->message(fd, msg_fd(fd,1367)); // Usage: @set <variable name> <value>
clif->message(fd, msg_fd(fd,1368)); // Usage: ex. "@set PoringCharVar 50"
clif->message(fd, msg_fd(fd,1369)); // Usage: ex. "@set PoringCharVarSTR$ Super Duper String"
diff --git a/src/map/clif.c b/src/map/clif.c
index 7be5c6978..ab13ffe1f 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -11794,7 +11794,7 @@ static void clif_parse_WisMessage(int fd, struct map_session_data *sd)
char *str = target + 4; // Skip the NPC: string part.
struct npc_data *nd;
if ((nd = npc->name2id(str))) {
- char split_data[NUM_WHISPER_VAR][CHAT_SIZE_MAX];
+ char split_data[NUM_WHISPER_VAR][SCRIPT_STRING_VAR_LENGTH + 1];
char *split;
char output[256];
diff --git a/src/map/intif.c b/src/map/intif.c
index a420b7204..276b40780 100644
--- a/src/map/intif.c
+++ b/src/map/intif.c
@@ -218,13 +218,13 @@ static int intif_saveregistry(struct map_session_data *sd)
plen += 1;
if( p->value ) {
- len = strlen(p->value)+1;
+ len = strlen(p->value);
- WFIFOB(inter_fd, plen) = (unsigned char)len;/* won't be higher; the column size is 254 */
+ WFIFOB(inter_fd, plen) = (unsigned char)len; // Won't be higher; the column size is 255.
plen += 1;
- safestrncpy(WFIFOP(inter_fd,plen), p->value, len);
- plen += len;
+ safestrncpy(WFIFOP(inter_fd, plen), p->value, len + 1);
+ plen += len + 1;
} else {
script->reg_destroy_single(sd,key.i64,&p->flag);
}
@@ -1025,7 +1025,7 @@ static void intif_parse_Registers(int fd)
* { keyLength(B), key(<keyLength>), index(L), valLength(B), val(<valLength>) }
**/
if (type) {
- char sval[254];
+ char sval[SCRIPT_STRING_VAR_LENGTH + 1];
for (i = 0; i < max; i++) {
int len = RFIFOB(fd, cursor);
safestrncpy(key, RFIFOP(fd, cursor + 1), min((int)sizeof(key), len));
@@ -1035,8 +1035,8 @@ static void intif_parse_Registers(int fd)
cursor += 4;
len = RFIFOB(fd, cursor);
- safestrncpy(sval, RFIFOP(fd, cursor + 1), min((int)sizeof(sval), len));
- cursor += len + 1;
+ safestrncpy(sval, RFIFOP(fd, cursor + 1), min((int)sizeof(sval), len + 1));
+ cursor += len + 2;
script->set_reg(NULL,sd,reference_uid(script->add_variable(key), index), key, sval, NULL);
}
diff --git a/src/map/mapreg_sql.c b/src/map/mapreg_sql.c
index 741505e17..2963637da 100644
--- a/src/map/mapreg_sql.c
+++ b/src/map/mapreg_sql.c
@@ -176,9 +176,9 @@ static bool mapreg_setregstr(int64 uid, const char *str)
if(name[1] != '@' && !mapreg->skip_insert) { //put returned null, so we must insert.
char tmp_str[(SCRIPT_VARNAME_LENGTH+1)*2+1];
- char tmp_str2[255*2+1];
+ char tmp_str2[SCRIPT_STRING_VAR_LENGTH * 2 + 1];
SQL->EscapeStringLen(map->mysql_handle, tmp_str, name, strnlen(name, SCRIPT_VARNAME_LENGTH+1));
- SQL->EscapeStringLen(map->mysql_handle, tmp_str2, str, strnlen(str, 255));
+ SQL->EscapeStringLen(map->mysql_handle, tmp_str2, str, strnlen(str, SCRIPT_STRING_VAR_LENGTH));
if( SQL_ERROR == SQL->Query(map->mysql_handle, "INSERT INTO `%s`(`varname`,`index`,`value`) VALUES ('%s','%u','%s')", mapreg->table, tmp_str, i, tmp_str2) )
Sql_ShowDebug(map->mysql_handle);
}
@@ -203,7 +203,7 @@ static void script_load_mapreg(void)
struct SqlStmt *stmt = SQL->StmtMalloc(map->mysql_handle);
char varname[SCRIPT_VARNAME_LENGTH+1];
int index;
- char value[255+1];
+ char value[SCRIPT_STRING_VAR_LENGTH + 1];
uint32 length;
if ( SQL_ERROR == SQL->StmtPrepare(stmt, "SELECT `varname`, `index`, `value` FROM `%s`", mapreg->table)
@@ -261,8 +261,8 @@ static void script_save_mapreg(void)
if( SQL_ERROR == SQL->Query(map->mysql_handle, "UPDATE `%s` SET `value`='%d' WHERE `varname`='%s' AND `index`='%d' LIMIT 1", mapreg->table, m->u.i, name, i) )
Sql_ShowDebug(map->mysql_handle);
} else {
- char tmp_str2[2*255+1];
- SQL->EscapeStringLen(map->mysql_handle, tmp_str2, m->u.str, safestrnlen(m->u.str, 255));
+ char tmp_str2[SCRIPT_STRING_VAR_LENGTH * 2 + 1];
+ SQL->EscapeStringLen(map->mysql_handle, tmp_str2, m->u.str, safestrnlen(m->u.str, SCRIPT_STRING_VAR_LENGTH));
if( SQL_ERROR == SQL->Query(map->mysql_handle, "UPDATE `%s` SET `value`='%s' WHERE `varname`='%s' AND `index`='%d' LIMIT 1", mapreg->table, tmp_str2, name, i) )
Sql_ShowDebug(map->mysql_handle);
}
diff --git a/src/map/npc_chat.c b/src/map/npc_chat.c
index 0ca84cff4..0df323e96 100644
--- a/src/map/npc_chat.c
+++ b/src/map/npc_chat.c
@@ -394,7 +394,8 @@ static int npc_chat_sub(struct block_list *bl, va_list ap)
// save out the matched strings
for (i = 0; i < r; i++)
{
- char var[15], val[255];
+ char var[SCRIPT_VARNAME_LENGTH + 1];
+ char val[SCRIPT_STRING_VAR_LENGTH + 1];
snprintf(var, sizeof(var), "$@p%i$", i);
libpcre->copy_substring(msg, offsets, r, i, val, sizeof(val));
script->set_var(sd, var, val);
diff --git a/src/map/script.c b/src/map/script.c
index 45c954dc0..347ef3d2a 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -3395,6 +3395,32 @@ static void set_reg_instance_num(struct script_state *st, int64 num, const char
}
/**
+ * Validates if a variable is permanent (stored in database) by passed variable name.
+ *
+ * @param name The variable name to validate.
+ * @return True if variable is permanent, otherwise false.
+ *
+ **/
+static bool script_is_permanent_variable(const char *name)
+{
+ nullpo_retr(false, name);
+
+ if (strlen(name) == 0)
+ return false;
+
+ if (ISALNUM(name[0]) != 0)
+ return true; // Permanent characater variable.
+
+ if (name[0] == '#')
+ return true; // Permanent (global) account variable.
+
+ if (strlen(name) > 1 && name[0] == '$' && ISALNUM(name[1]) != 0)
+ return true; // Permanent server variable.
+
+ return false;
+}
+
+/**
* Stores the value of a script variable
*
* @param st current script state.
@@ -3439,6 +3465,18 @@ static int set_reg(struct script_state *st, struct map_session_data *sd, int64 n
if (is_string_variable(name)) {// string variable
const char *str = (const char*)value;
+ if (script->is_permanent_variable(name) && strlen(str) > SCRIPT_STRING_VAR_LENGTH) {
+ ShowError("script:set_reg: Value of variable %s is too long: %lu! Maximum is %d. Skipping...\n",
+ name, strlen(str), SCRIPT_STRING_VAR_LENGTH);
+
+ if (st != NULL) {
+ script->reportsrc(st);
+ st->state = END;
+ }
+
+ return 0;
+ }
+
switch (prefix) {
case '@':
if (ref) {
@@ -28255,6 +28293,7 @@ void script_defaults(void)
script->load_parameters = script_load_parameters;
script->print_line = script_print_line;
script->errorwarning_sub = script_errorwarning_sub;
+ script->is_permanent_variable = script_is_permanent_variable;
script->set_reg = set_reg;
script->set_reg_ref_str = set_reg_npcscope_str;
script->set_reg_pc_ref_str = set_reg_pc_ref_str;
diff --git a/src/map/script.h b/src/map/script.h
index 511497a66..5fa81dc0e 100644
--- a/src/map/script.h
+++ b/src/map/script.h
@@ -984,6 +984,7 @@ struct script_interface {
void (*load_parameters) (void);
const char* (*print_line) (StringBuf *buf, const char *p, const char *mark, int line);
void (*errorwarning_sub) (StringBuf *buf, const char *src, const char *file, int start_line, const char *error_msg, const char *error_pos);
+ bool (*is_permanent_variable) (const char *name);
int (*set_reg) (struct script_state *st, struct map_session_data *sd, int64 num, const char *name, const void *value, struct reg_db *ref);
void (*set_reg_ref_str) (struct script_state* st, struct reg_db *n, int64 num, const char* name, const char *str);
void (*set_reg_pc_ref_str) (struct script_state* st, struct reg_db *n, int64 num, const char* name, const char *str);