S32 LLScriptHeapRunTime::catStrings(S32 address1, S32 address2) { if (!mBuffer) return 0; S32 dataaddress1 = address1 + 2*LSCRIPTDataSize[LST_INTEGER] + 1; S32 dataaddress2 = address2 + 2*LSCRIPTDataSize[LST_INTEGER] + 1; S32 toffset1 = dataaddress1; safe_heap_bytestream_count_char(mBuffer, toffset1); S32 toffset2 = dataaddress2; safe_heap_bytestream_count_char(mBuffer, toffset2); // calculate new string size S32 size1 = toffset1 - dataaddress1; S32 size2 = toffset2 - dataaddress2; S32 newbuffer = size1 + size2 - 1; char *temp = new char[newbuffer]; // get the strings bytestream2char(temp, mBuffer, dataaddress1); bytestream2char(temp + size1 - 1, mBuffer, dataaddress2); decreaseRefCount(address1); decreaseRefCount(address2); S32 retaddress = addData(temp); return retaddress; }
void lsa_fprint_heap(U8 *buffer, LLFILE *fp) { S32 offset = get_register(buffer, LREG_HR); S32 readoffset; S32 ivalue; F32 fpvalue; LLVector3 vvalue; LLQuaternion qvalue; char string[4096]; /*Flawfinder: ignore*/ LLScriptAllocEntry entry; bytestream2alloc_entry(entry, buffer, offset); while (offset + entry.mSize < MAX_HEAP_SIZE) { fprintf(fp, "[0x%X] ", offset); fprintf(fp, "%s ", LSCRIPTTypeNames[entry.mType]); fprintf(fp, "Ref Count: %d ", entry.mReferenceCount); fprintf(fp, "Size: %d = ", entry.mSize); readoffset = offset; switch(entry.mType) { case LST_INTEGER: ivalue = bytestream2integer(buffer, readoffset); fprintf(fp, "%d\n", ivalue); break; case LST_FLOATINGPOINT: fpvalue = bytestream2float(buffer, readoffset); fprintf(fp, "%f\n", fpvalue); break; case LST_STRING: bytestream2char(string, buffer, readoffset, sizeof(string)); fprintf(fp, "%s\n", string); break; case LST_KEY: bytestream2char(string, buffer, readoffset, sizeof(string)); fprintf(fp, "%s\n", string); break; case LST_VECTOR: bytestream2vector(vvalue, buffer, readoffset); fprintf(fp, "< %f, %f, %f >\n", vvalue.mV[VX], vvalue.mV[VY], vvalue.mV[VZ]); break; case LST_QUATERNION: bytestream2quaternion(qvalue, buffer, readoffset); fprintf(fp, "< %f, %f, %f, %f >\n", qvalue.mQ[VX], qvalue.mQ[VY], qvalue.mQ[VZ], qvalue.mQ[VS]); break; case LST_LIST: ivalue = bytestream2integer(buffer, readoffset); fprintf(fp, "%d\n", ivalue); break; default: fprintf(fp, "\n"); break; } offset += entry.mSize; bytestream2alloc_entry(entry, buffer, offset); } fprintf(fp, "[0x%X] ", offset); fprintf(fp, "%s ", LSCRIPTTypeNames[entry.mType]); fprintf(fp, "Ref Count: %d ", entry.mReferenceCount); fprintf(fp, "Size: %d", entry.mSize); fprintf(fp, "\n"); }
LLScriptLibData *lsa_get_data(U8 *buffer, S32 &offset, BOOL b_dec_ref) { if (get_register(buffer, LREG_FR)) return (new LLScriptLibData); S32 orig_offset = offset; // this bit of nastiness is to get around that code paths to local variables can result in lack of initialization // and function clean up of ref counts isn't based on scope (a mistake, I know) offset += get_register(buffer, LREG_HR) - 1; if ( (offset < get_register(buffer, LREG_HR)) ||(offset >= get_register(buffer, LREG_HP))) { set_fault(buffer, LSRF_BOUND_CHECK_ERROR); return (new LLScriptLibData); } LLScriptAllocEntry entry; bytestream2alloc_entry(entry, buffer, offset); LLScriptLibData *retval = new LLScriptLibData; if (!entry.mType) { set_fault(buffer, LSRF_HEAP_ERROR); return retval; } retval->mType = (LSCRIPTType)entry.mType; if (entry.mType != LST_LIST) { switch(entry.mType) { case LST_INTEGER: retval->mInteger = bytestream2integer(buffer, offset); break; case LST_FLOATINGPOINT: retval->mFP = bytestream2float(buffer, offset); break; case LST_KEY: bytestream2char(gLSAStringRead, buffer, offset, sizeof(gLSAStringRead)); // global sring buffer? for real? :( retval->mKey = new char[strlen(gLSAStringRead) + 1]; /*Flawfinder: ignore*/ strcpy(retval->mKey, gLSAStringRead); /*Flawfinder: ignore*/ break; case LST_STRING: bytestream2char(gLSAStringRead, buffer, offset, sizeof(gLSAStringRead)); retval->mString = new char[strlen(gLSAStringRead) + 1]; /*Flawfinder: ignore*/ strcpy(retval->mString, gLSAStringRead); /*Flawfinder: ignore*/ break; case LST_VECTOR: bytestream2vector(retval->mVec, buffer, offset); break; case LST_QUATERNION: bytestream2quaternion(retval->mQuat, buffer, offset); break; default: break; } } else { // get length of list S32 i, length = bytestream2integer(buffer, offset); LLScriptLibData *tip = retval; for (i = 0; i < length; i++) { S32 address = bytestream2integer(buffer, offset); tip->mListp = lsa_get_data(buffer, address, FALSE); tip = tip->mListp; } } if (retval->checkForMultipleLists()) { set_fault(buffer, LSRF_NESTING_LISTS); } if (b_dec_ref) { lsa_decrease_ref_count(buffer, orig_offset); } return retval; }