]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - prvm_cmds.c
PRVM: disallow changing read-only cvars
[xonotic/darkplaces.git] / prvm_cmds.c
index fc39fa33067c6ea2440d4f982835f2969dfcd062..5a86622243f64fe7fafc0208701632f5d36eb095 100644 (file)
@@ -27,6 +27,10 @@ void VM_Warning(prvm_prog_t *prog, const char *fmt, ...)
        va_list argptr;
        char msg[MAX_INPUTLINE];
        static double recursive = -1;
+       int outfd = sys.outfd;
+
+       // set output to stderr
+       sys.outfd = fileno(stderr);
 
        va_start(argptr,fmt);
        dpvsnprintf(msg,sizeof(msg),fmt,argptr);
@@ -41,6 +45,9 @@ void VM_Warning(prvm_prog_t *prog, const char *fmt, ...)
                PRVM_PrintState(prog, 0);
                recursive = -1;
        }
+
+       // restore configured outfd
+       sys.outfd = outfd;
 }
 
 
@@ -321,6 +328,10 @@ static qbool checkextension(prvm_prog_t *prog, const char *name)
                        if (!strcasecmp("DP_QC_DIGEST_SHA256", name))
                                return Crypto_Available();
 
+                       // special shreck for libcurl
+                       if (!strcasecmp("DP_QC_URI_GET", name) || !strcasecmp("DP_QC_URI_POST", name))
+                               return Curl_Available();
+
                        return true;
                }
        }
@@ -795,12 +806,25 @@ void cvar_set (string,string, ...)
 void VM_cvar_set(prvm_prog_t *prog)
 {
        const char *name;
-       char string[VM_STRINGTEMP_LENGTH];
+       char value[VM_STRINGTEMP_LENGTH];
+       cvar_t *cvar;
+
        VM_SAFEPARMCOUNTRANGE(2,8,VM_cvar_set);
-       VM_VarString(prog, 1, string, sizeof(string));
        name = PRVM_G_STRING(OFS_PARM0);
        VM_CheckEmptyString(prog, name);
-       Cvar_Set(prog->console_cmd->cvars, name, string);
+       cvar = Cvar_FindVar(prog->console_cmd->cvars, name, prog->console_cmd->cvars_flagsmask);
+       if (!cvar)
+       {
+               VM_Warning(prog, "VM_cvar_set: variable %s not found\n", name);
+               return;
+       }
+       if (cvar->flags & CF_READONLY)
+       {
+               VM_Warning(prog, "VM_cvar_set: variable %s is read-only\n", cvar->name);
+               return;
+       }
+       VM_VarString(prog, 1, value, sizeof(value));
+       Cvar_SetQuick(cvar, value);
 }
 
 /*
@@ -2318,11 +2342,11 @@ void VM_strtoupper(prvm_prog_t *prog)
 =========
 VM_strcat
 
-string strcat(string,string,...[string])
+string strcat(string s, string...)
 =========
 */
-//string(string s1, string s2) strcat = #115;
-// concatenates two strings (for example "abc", "def" would return "abcdef")
+//string(string s, string...) strcat = #115;
+// concatenates strings (for example "abc", "def" would return "abcdef")
 // and returns as a tempstring
 void VM_strcat(prvm_prog_t *prog)
 {
@@ -2615,7 +2639,7 @@ void VM_tokenize (prvm_prog_t *prog)
 
        VM_SAFEPARMCOUNT(1,VM_tokenize);
 
-       strlcpy(tokenize_string, PRVM_G_STRING(OFS_PARM0), sizeof(tokenize_string));
+       dp_strlcpy(tokenize_string, PRVM_G_STRING(OFS_PARM0), sizeof(tokenize_string));
        p = tokenize_string;
 
        num_tokens = 0;
@@ -2646,7 +2670,7 @@ void VM_tokenize_console (prvm_prog_t *prog)
 
        VM_SAFEPARMCOUNT(1, VM_tokenize_console);
 
-       strlcpy(tokenize_string, PRVM_G_STRING(OFS_PARM0), sizeof(tokenize_string));
+       dp_strlcpy(tokenize_string, PRVM_G_STRING(OFS_PARM0), sizeof(tokenize_string));
        p = tokenize_string;
 
        num_tokens = 0;
@@ -2696,7 +2720,7 @@ void VM_tokenizebyseparator (prvm_prog_t *prog)
 
        VM_SAFEPARMCOUNTRANGE(2, 8,VM_tokenizebyseparator);
 
-       strlcpy(tokenize_string, PRVM_G_STRING(OFS_PARM0), sizeof(tokenize_string));
+       dp_strlcpy(tokenize_string, PRVM_G_STRING(OFS_PARM0), sizeof(tokenize_string));
        p = tokenize_string;
 
        numseparators = 0;
@@ -3064,13 +3088,21 @@ float   mod(float val, float m)
 */
 void VM_modulo(prvm_prog_t *prog)
 {
-       prvm_int_t val, m;
+       vec_t val, m;
+
        VM_SAFEPARMCOUNT(2, VM_modulo);
 
-       val = (prvm_int_t) PRVM_G_FLOAT(OFS_PARM0);
-       m       = (prvm_int_t) PRVM_G_FLOAT(OFS_PARM1);
+       val = PRVM_G_FLOAT(OFS_PARM0);
+       m   = PRVM_G_FLOAT(OFS_PARM1);
 
-       PRVM_G_FLOAT(OFS_RETURN) = (prvm_vec_t) (val % m);
+       // matches how gmqcc implements % when mod() builtin isn't defined, and FTEQW mod()
+       if (m)
+               PRVM_G_FLOAT(OFS_RETURN) = val - m * (prvm_int_t)(val / m);
+       else
+       {
+               VM_Warning(prog, "Attempted modulo of %f by zero\n", val);
+               PRVM_G_FLOAT(OFS_RETURN) = 0;
+       }
 }
 
 static void VM_Search_Init(prvm_prog_t *prog)
@@ -3308,7 +3340,7 @@ void VM_findkeysforcommand(prvm_prog_t *prog)
 
        ret[0] = 0;
        for(i = 0; i < FKFC_NUMKEYS; i++)
-               strlcat(ret, va(vabuf, sizeof(vabuf), " \'%i\'", keys[i]), sizeof(ret));
+               dp_strlcat(ret, va(vabuf, sizeof(vabuf), " \'%i\'", keys[i]), sizeof(ret));
 
        PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, ret);
 }
@@ -3694,7 +3726,7 @@ void VM_altstr_set(prvm_prog_t *prog)
                if( *in == '\'' || (*in == '\\' && !*++in) )
                        break;
 
-       strlcpy(out, in, outstr + sizeof(outstr) - out);
+       dp_strlcpy(out, in, outstr + sizeof(outstr) - out);
        PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString(prog,  outstr );
 }
 
@@ -3733,7 +3765,7 @@ void VM_altstr_ins(prvm_prog_t *prog)
        for( ; *set ; *out++ = *set++ );
        *out++ = '\'';
 
-       strlcpy(out, in, outstr + sizeof(outstr) - out);
+       dp_strlcpy(out, in, outstr + sizeof(outstr) - out);
        PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString(prog,  outstr );
 }
 
@@ -4085,8 +4117,8 @@ void VM_buf_implode (prvm_prog_t *prog)
                        l += (i > 0 ? strlen(sep) : 0) + strlen(stringbuffer->strings[i]);
                        if (l >= sizeof(k) - 1)
                                break;
-                       strlcat(k, sep, sizeof(k));
-                       strlcat(k, stringbuffer->strings[i], sizeof(k));
+                       dp_strlcat(k, sep, sizeof(k));
+                       dp_strlcat(k, stringbuffer->strings[i], sizeof(k));
                }
        }
        PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, k);
@@ -4521,7 +4553,7 @@ void VM_bufstr_find(prvm_prog_t *prog)
                match = PRVM_G_STRING(OFS_PARM1);
        else
        {
-               strlcpy(string, PRVM_G_STRING(OFS_PARM1), sizeof(string));
+               dp_strlcpy(string, PRVM_G_STRING(OFS_PARM1), sizeof(string));
                match = detect_match_rule(string, &matchrule);
        }
        matchlen = (int)strlen(match);
@@ -4567,7 +4599,7 @@ void VM_matchpattern(prvm_prog_t *prog)
                match = PRVM_G_STRING(OFS_PARM1);
        else
        {
-               strlcpy(string, PRVM_G_STRING(OFS_PARM1), sizeof(string));
+               dp_strlcpy(string, PRVM_G_STRING(OFS_PARM1), sizeof(string));
                match = detect_match_rule(string, &matchrule);
        }
 
@@ -5024,7 +5056,7 @@ void VM_infoadd (prvm_prog_t *prog)
        key = PRVM_G_STRING(OFS_PARM1);
        VM_VarString(prog, 2, value, sizeof(value));
 
-       strlcpy(temp, info, VM_STRINGTEMP_LENGTH);
+       dp_strlcpy(temp, info, VM_STRINGTEMP_LENGTH);
 
        InfoString_SetValue(temp, VM_STRINGTEMP_LENGTH, key, value);
 
@@ -5443,7 +5475,7 @@ void VM_uri_get (prvm_prog_t *prog)
                        // POST: we sign postdata \0 query string
                        size_t ll;
                        handle->sigdata = (char *)Z_Malloc(8192);
-                       strlcpy(handle->sigdata, "X-D0-Blind-ID-Detached-Signature: ", 8192);
+                       dp_strlcpy(handle->sigdata, "X-D0-Blind-ID-Detached-Signature: ", 8192);
                        l = strlen(handle->sigdata);
                        handle->siglen = Crypto_SignDataDetached(handle->postdata, handle->postlen + 1 + lq, postkeyid, handle->sigdata + l, 8192 - l);
                        if(!handle->siglen)
@@ -5463,7 +5495,7 @@ void VM_uri_get (prvm_prog_t *prog)
                        handle->sigdata[handle->siglen] = 0;
                }
 out1:
-               strlcpy(handle->posttype, posttype, sizeof(handle->posttype));
+               dp_strlcpy(handle->posttype, posttype, sizeof(handle->posttype));
                ret = Curl_Begin_ToMemory_POST(url, handle->sigdata, 0, handle->posttype, handle->postdata, handle->postlen, (unsigned char *) handle->buffer, sizeof(handle->buffer), uri_to_string_callback, handle);
        }
        else
@@ -5473,7 +5505,7 @@ out1:
                        // GET: we sign JUST the query string
                        size_t l, ll;
                        handle->sigdata = (char *)Z_Malloc(8192);
-                       strlcpy(handle->sigdata, "X-D0-Blind-ID-Detached-Signature: ", 8192);
+                       dp_strlcpy(handle->sigdata, "X-D0-Blind-ID-Detached-Signature: ", 8192);
                        l = strlen(handle->sigdata);
                        handle->siglen = Crypto_SignDataDetached(query_string, lq, postkeyid, handle->sigdata + l, 8192 - l);
                        if(!handle->siglen)