[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[sc-dev] s_recvoscmsg bug causes crashes - heureka - [commit?]



Problem: osc responder crashes sclang on recieving a string larger than 255.

Reason: This is due to the fact that an incoming string is converted into a Symbol by sclang. When creating a symbol from a string, the string normally is truncated to 255 characters. Seemingly the attempt to create a symbol larger than this causes the sclang to crash.


// the problem is in PyrObject* ConvertOSCMessage(int inSize, char *inData):

case 's' :
                    SetSymbol(slots+i+1, getsym(msg.gets()));
                    //post("sym '%s'\n", slots[i+1].us->name);
                    break;

// I have fixed it as follows:

		inchars = msg.gets();
		size = strlen(inchars);


		if(size < 256) {
			SetSymbol(slots+i+1, getsym(inchars));
					} else {
PyrString *strobj = newPyrStringN(g->gc, size, 0, true);
			memcpy(strobj->s, inchars, size);
			SetObject(slots+i+1, strobj);
		}


// ok to commit ?

//// diff //////




Index: OSCData.cpp
===================================================================
RCS file: /cvsroot/supercollider/SuperCollider3/source/lang/LangPrimSource/OSCData.cpp,v
retrieving revision 1.43
diff -p -b -B -r1.43 OSCData.cpp
*** OSCData.cpp 20 Nov 2004 13:35:40 -0000      1.43
--- OSCData.cpp 26 Nov 2004 17:21:58 -0000
*************** PyrObject* ConvertOSCMessage(int inSize,
*** 597,602 ****
--- 597,604 ----
for (int i=0; i<numElems; ++i) {
              char tag = msg.nextTag();
+                       char *inchars;
+                       int size;
              //post("%d %c\n", i, tag);
              switch (tag) {
                  case 'i' :
*************** PyrObject* ConvertOSCMessage(int inSize,
*** 609,615 ****
                      SetFloat(slots+i+1, msg.getd());
                      break;
                  case 's' :
!                     SetSymbol(slots+i+1, getsym(msg.gets()));
                      //post("sym '%s'\n", slots[i+1].us->name);
                      break;
                  case 'b' :
--- 611,627 ----
                      SetFloat(slots+i+1, msg.getd());
                      break;
                  case 's' :
!                                       inchars = msg.gets();
!                                       size = strlen(inchars);
!                                       if(size < 256) {
! SetSymbol(slots+i+1, getsym(inchars));
!                                       } else {
! PyrString *strobj = newPyrStringN(g->gc, size, 0, true); ! memcpy(strobj->s, inchars, size); ! SetObject(slots+i+1, strobj);
!
!                                       }
!
                      //post("sym '%s'\n", slots[i+1].us->name);
                      break;
                  case 'b' :







// full method:


PyrObject* ConvertOSCMessage(int inSize, char *inData)
{
	char *cmdName = inData;
	int cmdNameLen = OSCstrlen(cmdName);
	sc_msg_iter msg(inSize - cmdNameLen, inData + cmdNameLen);
int numElems;
        if (inSize == cmdNameLen) {
            numElems = 0;
        } else {
			if (!msg.tags) {
				numElems = 0;
error("OSC messages must have type tags. %s\n", cmdName);
			} else {
				numElems = strlen(msg.tags);
			}
        }
        //post("tags %s %d\n", msg.tags, numElems);
VMGlobals *g = gMainVMGlobals;
        PyrObject *obj = newPyrArray(g->gc, numElems + 1, 0, false);
        PyrSlot *slots = obj->slots;

        SetSymbol(slots+0, getsym(cmdName));
for (int i=0; i<numElems; ++i) {
            char tag = msg.nextTag();
            //post("%d %c\n", i, tag);
            switch (tag) {
                case 'i' :
                    SetInt(slots+i+1, msg.geti());
                    break;
                case 'f' :
                    SetFloat(slots+i+1, msg.getf());
                    break;
                case 'd' :
                    SetFloat(slots+i+1, msg.getd());
                    break;
                case 's' :
                    SetSymbol(slots+i+1, getsym(msg.gets()));
                    //post("sym '%s'\n", slots[i+1].us->name);
                    break;
                case 'b' :
		    SetObject(slots+i+1, (PyrObject*)MsgToInt8Array(msg));
                    break;
            }
        }
        obj->size = numElems + 1;
        return obj;
}





//////////////////////////////////////////








// a while ago, Rohrhuber wrote:

(
n = NetAddr("127.0.0.1", 57120);
o.remove;
o = OSCresponder(n, '/client', { arg time, responder, msg;
				msg.postln;

}).add;
)

// this is fine (bundle size 300 bytes)
(
x = String.fill(260, $_);
b = ["/client", "ok", x];
[b].bundleSize;
)

n.sendMsg(*b);
n.sendBundle(nil, b);


// this crashes (bundle size 320 bytes)

(
x = String.fill(280, $_);
b = ["/client", "ok", x];
[b].bundleSize;
)

n.sendMsg(*b);
n.sendBundle(nil, b); // same here


/////////////////

a possible source is in PerformOSCMessage

void PerformOSCMessage(int inSize, char *inData, PyrObject *replyObj)
{
PyrObject *arrayObj = ConvertOSCMessage(inSize, inData); // call virtual machine to handle message
    VMGlobals *g = gMainVMGlobals;
    ++g->sp; SetObject(g->sp, g->process);
    ++g->sp; SetFloat(g->sp, elapsedTime());	// time
    ++g->sp; SetObject(g->sp, replyObj);
++g->sp; SetObject(g->sp, arrayObj); // commenting out this SetObject causes // the crash not to happen

    runInterpreter(g, s_recvoscmsg, 4);

}

--








.
_______________________________________________
sc-dev mailing list
sc-dev@xxxxxxxxxxxxxxx
http://www.create.ucsb.edu/mailman/listinfo/sc-dev
--








.