static qboolean checkextension(const char *name)
{
int len;
- char *e, *start;
+ const char *e, *start;
len = (int)strlen(name);
for (e = prog->extensionstring;*e;e++)
double starttime;
float id;
char buffer[MAX_INPUTLINE];
+ unsigned char *postdata; // free when uri_to_prog_t is freed
+ size_t postlen;
+ char *sigdata; // free when uri_to_prog_t is freed
+ size_t siglen;
}
uri_to_prog_t;
if(!PRVM_ProgLoaded(handle->prognr))
{
// curl reply came too late... so just drop it
+ if(handle->postdata)
+ Z_Free(handle->postdata);
+ if(handle->sigdata)
+ Z_Free(handle->sigdata);
Z_Free(handle);
return;
}
}
PRVM_End;
+ if(handle->postdata)
+ Z_Free(handle->postdata);
+ if(handle->sigdata)
+ Z_Free(handle->sigdata);
Z_Free(handle);
}
float id;
qboolean ret;
uri_to_prog_t *handle;
+ const char *posttype = NULL;
+ const char *postseparator = NULL;
+ int poststringbuffer = -1;
+ int postkeyid = -1;
+ const char *query_string = NULL;
+ size_t lq;
if(!prog->funcoffsets.URI_Get_Callback)
PRVM_ERROR("uri_get called by %s without URI_Get_Callback defined", PRVM_NAME);
- VM_SAFEPARMCOUNT(2, VM_uri_get);
+ VM_SAFEPARMCOUNTRANGE(2, 6, VM_uri_get);
url = PRVM_G_STRING(OFS_PARM0);
id = PRVM_G_FLOAT(OFS_PARM1);
+ if(prog->argc >= 3)
+ posttype = PRVM_G_STRING(OFS_PARM2);
+ if(prog->argc >= 4)
+ postseparator = PRVM_G_STRING(OFS_PARM3);
+ if(prog->argc >= 5)
+ poststringbuffer = PRVM_G_FLOAT(OFS_PARM4);
+ if(prog->argc >= 6)
+ postkeyid = PRVM_G_FLOAT(OFS_PARM5);
handle = (uri_to_prog_t *) Z_Malloc(sizeof(*handle)); // this can't be the prog's mem pool, as curl may call the callback later!
+ query_string = strchr(url, '?');
+ if(query_string)
+ ++query_string;
+ lq = query_string ? strlen(query_string) : 0;
+
handle->prognr = PRVM_GetProgNr();
handle->starttime = prog->starttime;
handle->id = id;
- ret = Curl_Begin_ToMemory(url, 0, (unsigned char *) handle->buffer, sizeof(handle->buffer), uri_to_string_callback, handle);
+ if(postseparator)
+ {
+ size_t l = strlen(postseparator);
+ if(poststringbuffer >= 0)
+ {
+ size_t ltotal;
+ int i;
+ // "implode"
+ prvm_stringbuffer_t *stringbuffer;
+ stringbuffer = (prvm_stringbuffer_t *)Mem_ExpandableArray_RecordAtIndex(&prog->stringbuffersarray, poststringbuffer);
+ if(!stringbuffer)
+ {
+ VM_Warning("uri_get: invalid buffer %i used in %s\n", (int)PRVM_G_FLOAT(OFS_PARM0), PRVM_NAME);
+ return;
+ }
+ ltotal = 0;
+ for(i = 0;i < stringbuffer->num_strings;i++)
+ {
+ if(i > 0)
+ ltotal += l;
+ if(stringbuffer->strings[i])
+ ltotal += strlen(stringbuffer->strings[i]);
+ }
+ handle->postdata = (unsigned char *)Z_Malloc(ltotal + 1 + lq);
+ handle->postlen = ltotal;
+ ltotal = 0;
+ for(i = 0;i < stringbuffer->num_strings;i++)
+ {
+ if(i > 0)
+ {
+ memcpy(handle->postdata + ltotal, postseparator, l);
+ ltotal += l;
+ }
+ if(stringbuffer->strings[i])
+ {
+ memcpy(handle->postdata + ltotal, stringbuffer->strings[i], strlen(stringbuffer->strings[i]));
+ ltotal += strlen(stringbuffer->strings[i]);
+ }
+ }
+ if(ltotal != handle->postlen)
+ PRVM_ERROR ("%s: string buffer content size mismatch, possible overrun", PRVM_NAME);
+ }
+ else
+ {
+ handle->postdata = (unsigned char *)Z_Malloc(l + 1 + lq);
+ handle->postlen = l;
+ memcpy(handle->postdata, postseparator, l);
+ }
+ handle->postdata[handle->postlen] = 0;
+ if(query_string)
+ memcpy(handle->postdata + handle->postlen + 1, query_string, lq);
+ if(postkeyid >= 0)
+ {
+ // 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);
+ l = strlen(handle->sigdata);
+ handle->siglen = Crypto_SignDataDetached(handle->postdata, handle->postlen + 1 + lq, postkeyid, handle->sigdata + l, 8192 - l);
+ if(!handle->siglen)
+ {
+ Z_Free(handle->sigdata);
+ handle->sigdata = NULL;
+ goto out1;
+ }
+ ll = base64_encode((unsigned char *) (handle->sigdata + l), handle->siglen, 8192 - l - 1);
+ if(!ll)
+ {
+ Z_Free(handle->sigdata);
+ handle->sigdata = NULL;
+ goto out1;
+ }
+ handle->siglen = l + ll;
+ handle->sigdata[handle->siglen] = 0;
+ }
+out1:
+ ret = Curl_Begin_ToMemory_POST(url, handle->sigdata, 0, posttype, handle->postdata, handle->postlen, (unsigned char *) handle->buffer, sizeof(handle->buffer), uri_to_string_callback, handle);
+ }
+ else
+ {
+ if(postkeyid >= 0 && query_string)
+ {
+ // 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);
+ l = strlen(handle->sigdata);
+ handle->siglen = Crypto_SignDataDetached(query_string, lq, postkeyid, handle->sigdata + l, 8192 - l);
+ if(!handle->siglen)
+ {
+ Z_Free(handle->sigdata);
+ handle->sigdata = NULL;
+ goto out2;
+ }
+ ll = base64_encode((unsigned char *) (handle->sigdata + l), handle->siglen, 8192 - l - 1);
+ if(!ll)
+ {
+ Z_Free(handle->sigdata);
+ handle->sigdata = NULL;
+ goto out2;
+ }
+ handle->siglen = l + ll;
+ handle->sigdata[handle->siglen] = 0;
+ }
+out2:
+ handle->postdata = NULL;
+ handle->postlen = 0;
+ ret = Curl_Begin_ToMemory(url, 0, (unsigned char *) handle->buffer, sizeof(handle->buffer), uri_to_string_callback, handle);
+ }
if(ret)
{
PRVM_G_INT(OFS_RETURN) = 1;
}
else
{
+ if(handle->postdata)
+ Z_Free(handle->postdata);
+ if(handle->sigdata)
+ Z_Free(handle->sigdata);
Z_Free(handle);
PRVM_G_INT(OFS_RETURN) = 0;
}
skeleton_t *skeleton;
int skeletonindex = -1;
qboolean need = false;
- if(!model->AnimateVertices)
+ if(!(model->surfmesh.isanimated && model->AnimateVertices))
{
animatemodel_cache.data_vertex3f = model->surfmesh.data_vertex3f;
animatemodel_cache.data_svector3f = model->surfmesh.data_svector3f;
need |= (animatemodel_cache.model != model);
VM_GenerateFrameGroupBlend(ed->priv.server->framegroupblend, ed);
VM_FrameBlendFromFrameGroupBlend(ed->priv.server->frameblend, ed->priv.server->framegroupblend, model);
- need |= (memcmp(&animatemodel_cache.frameblend, &ed->priv.server->frameblend, sizeof(ed->priv.server->frameblend)));
+ need |= (memcmp(&animatemodel_cache.frameblend, &ed->priv.server->frameblend, sizeof(ed->priv.server->frameblend))) != 0;
if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.skeletonindex))) skeletonindex = (int)val->_float - 1;
if (!(skeletonindex >= 0 && skeletonindex < MAX_EDICTS && (skeleton = prog->skeletons[skeletonindex]) && skeleton->model->num_bones == ed->priv.server->skeleton.model->num_bones))
skeleton = NULL;
need |= (animatemodel_cache.skeleton_p != skeleton);
if(skeleton)
- need |= (memcmp(&animatemodel_cache.skeleton, skeleton, sizeof(ed->priv.server->skeleton)));
+ need |= (memcmp(&animatemodel_cache.skeleton, skeleton, sizeof(ed->priv.server->skeleton))) != 0;
if(!need)
return;
if(model->surfmesh.num_vertices > animatemodel_cache.max_vertices)
if(animatemodel_cache.buf_svector3f) Mem_Free(animatemodel_cache.buf_svector3f);
if(animatemodel_cache.buf_tvector3f) Mem_Free(animatemodel_cache.buf_tvector3f);
if(animatemodel_cache.buf_normal3f) Mem_Free(animatemodel_cache.buf_normal3f);
- animatemodel_cache.buf_vertex3f = Mem_Alloc(prog->progs_mempool, sizeof(float[3]) * animatemodel_cache.max_vertices);
- animatemodel_cache.buf_svector3f = Mem_Alloc(prog->progs_mempool, sizeof(float[3]) * animatemodel_cache.max_vertices);
- animatemodel_cache.buf_tvector3f = Mem_Alloc(prog->progs_mempool, sizeof(float[3]) * animatemodel_cache.max_vertices);
- animatemodel_cache.buf_normal3f = Mem_Alloc(prog->progs_mempool, sizeof(float[3]) * animatemodel_cache.max_vertices);
+ animatemodel_cache.buf_vertex3f = (float *)Mem_Alloc(prog->progs_mempool, sizeof(float[3]) * animatemodel_cache.max_vertices);
+ animatemodel_cache.buf_svector3f = (float *)Mem_Alloc(prog->progs_mempool, sizeof(float[3]) * animatemodel_cache.max_vertices);
+ animatemodel_cache.buf_tvector3f = (float *)Mem_Alloc(prog->progs_mempool, sizeof(float[3]) * animatemodel_cache.max_vertices);
+ animatemodel_cache.buf_normal3f = (float *)Mem_Alloc(prog->progs_mempool, sizeof(float[3]) * animatemodel_cache.max_vertices);
}
animatemodel_cache.data_vertex3f = animatemodel_cache.buf_vertex3f;
animatemodel_cache.data_svector3f = animatemodel_cache.buf_svector3f;