Product Unlocking Bug

I’m writing a product unlocking class for use with Gumroad based on the OnlineUnlockStatusTutorial, and I’m having some weird issues around memory allocation and strings.

When this function gets called Ableton sometimes (but not always!) throws this error.

HEAP CORRUPTION DETECTED: after Normal block (#127956) at 0x000000002BD7E600.
CRT detected that the application wrote to memory after end of heap buffer.
(Press Retry to debug the application)

When I press Retry the debugger halts on the return true. If I dig down the callstack it’s halting on the juce::String destructor, which is trying to free the memory of unparsed. If I replace the instantiation of unparsed (which grabs its data from the buffer), with a hardcoded JSON string, everything works OK. Therefore, I think there’s an issue with the memory being freed when I’m creating a string from the HeapBlock.

The memory address of unparsed.text is 2 bytes after the address in the ableton error, which is further evidence that unparsed is the location of the issue.

Here’s a very condensed version of the function that does the heavy lifting. It’s mostly copypasted from the tutorial.


    bool verifyKey(juce::String& key)
    {
        // skipping some setup from the tutorial...

        if (stream->connect (nullptr))
        {
            // more setup...

            const size_t bufferSize = 2048; // this was made larger to accommodate the gumroad reply size
            juce::HeapBlock<char> buffer (bufferSize);

           // lots of stuff from the tut streaming into the buffer...

            // parse the json reply, and check values
            juce::String unparsed = { CharPointer_UTF8(buffer.get()) };
            juce::var json;
            juce::Result res = juce::JSON::parse({ CharPointer_UTF8(buffer.get()) }, json);
            juce::String parsed = juce::JSON::toString(json);

            // check overall failure / success
            if(res.failed())
                return false;
            if(! json["success"])
                return false;
            
            // check that we have expected properties
            if(!json.hasProperty("purchase"))
                return false;
            if(!json["purchase"].hasProperty("chargebacked"))
                return false;
            if(!json["purchase"].hasProperty("refunded"))
                return false;
            if(!json["purchase"].hasProperty("license_key"))
                return false;

            // check those properties are good
            if(json["purchase"]["chargebacked"])
                return false;
            if(json["purchase"]["refunded"])
                return false;
            if(json["purchase"]["license_key"] != key)
                return false;

            return true; // debugger halts here, call stack goes down into String destructor
        }

        return false;
    }

Last but not least, there’s some stuff I’ve omitted where I’m doing file IO in some other helper functions. I don’t think it’s causing the issue, but it might be useful context.

Thanks in advance for any and all help!

Update: It seems like changing CharPointer_UTF8 to CharPointer_ASCII solved it.
Anyone know why that might be?