hxcpp icon indicating copy to clipboard operation
hxcpp copied to clipboard

Allocating a huge string causes heap corruption

Open space-nuko opened this issue 3 years ago • 4 comments

I'm trying to compile an openfl application for the Windows target but am encountering heap corruption.

The swf loader tries to parse out a huge json string (4.4 million characters wide) with haxe's JsonParser and it eventually corrupts the heap, in GlobalAllocator::AllocMoreBlocks. This is the stack at the point the memory I watched was overwritten:

 	ApplicationMain-debug.exe!memset_repmovs() Line 67	Unknown
 	ApplicationMain-debug.exe!BlockDataInfo::clear() Line 779	C++
 	ApplicationMain-debug.exe!BlockDataInfo::BlockDataInfo(int inGid, BlockData * inData) Line 770	C++
 	ApplicationMain-debug.exe!GlobalAllocator::AllocMoreBlocks(bool & outForceCompact, bool inJustBorrowing) Line 3445	C++
 	ApplicationMain-debug.exe!GlobalAllocator::GetFreeBlock(int inRequiredBytes, hx::ImmixAllocator * inAlloc) Line 3523	C++
 	ApplicationMain-debug.exe!LocalAllocator::CallAlloc(int inSize, unsigned int inObjectFlags) Line 6156	C++
 	ApplicationMain-debug.exe!hx::InternalNew(int inSize, bool inIsObject) Line 6487	C++
>	ApplicationMain-debug.exe!hx::NewString(int inLen) Line 116	C++
 	ApplicationMain-debug.exe!GCStringDup<char>(const char * inStr, int inLen, int * outLen) Line 420	C++
 	ApplicationMain-debug.exe!String::substr(int inFirst, Dynamic inLen) Line 1982	C++
 	ApplicationMain-debug.exe!haxe::format::JsonParser_obj::parseString() Line 638	C++
 	ApplicationMain-debug.exe!haxe::format::JsonParser_obj::parseRec() Line 356	C++
 	ApplicationMain-debug.exe!haxe::format::JsonParser_obj::parseRec() Line 252	C++
 	ApplicationMain-debug.exe!haxe::format::JsonParser_obj::parseRec() Line 372	C++
 	ApplicationMain-debug.exe!haxe::format::JsonParser_obj::parseRec() Line 252	C++
 	ApplicationMain-debug.exe!haxe::format::JsonParser_obj::parseRec() Line 372	C++
 	ApplicationMain-debug.exe!haxe::format::JsonParser_obj::parseRec() Line 252	C++
 	ApplicationMain-debug.exe!haxe::format::JsonParser_obj::parseRec() Line 372	C++
 	ApplicationMain-debug.exe!haxe::format::JsonParser_obj::doParse() Line 52	C++
 	ApplicationMain-debug.exe!swf::exporters::animate::AnimateLibrary_obj::_hx_isInstanceOf(int)	C++
 	ApplicationMain-debug.exe!swf::exporters::animate::AnimateLibrary_obj::__register(void)	C++
 	ApplicationMain-debug.exe!lime::app::Future_obj::onComplete(class Dynamic)	C++
 	ApplicationMain-debug.exe!swf::exporters::animate::AnimateLibrary_obj::load(void)	C++

The newly allocated string is only 9 chars in length.

I'm not sure what's going on but I only noticed this when trying to load some rtti data attached to a Class object and noticed that the XML parser was failing with a different error message each time

space-nuko avatar Mar 27 '22 09:03 space-nuko

Also this may be an issue with threading since the stack is under a call inside a ThreadPool, and the loadLibrary method being called returns a Future. I tried making a minimal test project to reproduce the issue but couldn't trigger it (even when loading the JSON inside a future several times)

I can produce an actual binary/project if needed

space-nuko avatar Mar 27 '22 09:03 space-nuko

Here is a minimal repro

package;

import openfl.display.Sprite;
import lime.utils.Bytes;
import haxe.Json;

class Main extends Sprite {
	public function new() {
		super();

                var bytes = Bytes.fromFile("C:/path/to/huge.json");
                var s = bytes.getString(0, bytes.length);
                Json.parse(s);
	}
}

I also used these defines

    <haxedef name="HXCPP_CHECK_POINTER" if="cpp"/>
    <haxedef name="HXCPP_STACK_LINE" if="cpp"/>
    <haxedef name="HXCPP_STACK_TRACE" if="cpp"/>
    <haxedef name="HXCPP_DEBUG_LINK" if="cpp"/>
    <haxedef name="HXCPP_CATCH_SEGV" if="cpp"/>

space-nuko avatar Mar 27 '22 10:03 space-nuko

I'm constantly crashing on iOS, could it be affecting iOS?

barisyild avatar Apr 17 '22 00:04 barisyild

I also have this problem

rainyt avatar Feb 17 '23 04:02 rainyt