OnlineUnlockStatus: malloc error, garbage web response


#1

Hi there,

I’m trying to use OnlineUnlockStatus. I’ve implemented a form and marketplace status as per the tutorial. It works absolutely fine *some of the time. Otherwise I’m running into two sporadic problems that are very difficult to reproduce reliably:

(1)
The server returns garbage at the end of the <[VALID XML RESULT>. E.g.:

  • ‘\243’ Hundreds of times.
  • ‘\377’ Many times.
  • ‘?gF\360?\234H@Ќd?\346cq@\312\354\324?\2620%@dv)@’

(2)
After spamming the ‘register’ button tens of times to generate XML results for debugging, I get a malloc-related SIGABRT. These can vary (exact error and stack trace), but example errors are:

  • MainStage 3(1765,0x105263380) malloc: *** error for object 0x60800116b280: Invalid pointer dequeued from free list
  • MainStage 3(1739,0x70000bfe5000) malloc: *** error for object 0x131a40658: incorrect checksum for freed object - object was probably modified after being freed.

*** set a breakpoint in malloc_error_break to debug

I wonder if these problems are related. Any relevant thoughts would be really helpful!

Anticipating some follow-up questions:

Can you reproduce this problem with the OnlineUnlockStatus tutorial project?
Yes - Garbage responses (frequency and type similar)
Yes - Error after many registration attempts (bad access deep in JUCE core / Ob-C stuff that I don’t understand).
No - Exact errors (no malloc stuff). But malloc errors (so far as I’ve read) are usual symptoms of systemic problems so maybe this points to them.
— This is the case with JUCE master as well as my own local modded JUCE.

Do you get the same garbage responses calling the authorisation URL from the terminal?
No. Using cURL hundreds of times to call the exact same URL, every response is as expected.

Are you calling the same authorisation URL every time?
Yes, according to DBG (url);.

Are you using the correct request method?
Yes, the plugin uses POST as does the server-side implementation, as did my testing using cURL in the terminal.

Have you messed with the JUCE code?
Yes, I had to to include a licenceType parameter. But I was seeing these unusual responses even before I did that.

Is there a pattern to the garbage responses?
There seem to be only a handful of garbage strings. But the order of these is unpredictable.

Is there a pattern to the number of times you press ‘register’ before you get an error?
No. I have tested this using the exact same credentials every time.

Is this a local server? Is it using SSL?
Yes, this is a local server hosted with Laravel Valet. I have used $ valet secure to force HTTPS. In the browser the local site uses HTTPS. The cURL tests were all over HTTPS.

Where are you getting the response text from?
OnlineUnlockStatus::AttemptWebserverUnlock (args) { ... auto reply = readReplyFromWebserver (email, password); DBG (reply); ... }


#2

Came across a similar problem with the garbage at end of web response (not for OnlineLockStatus, but checking for latest version string). The problem was using an uninitialised buffer.

            const size_t bufferSize = 0x8000;
            HeapBlock<char> buffer (bufferSize);
            buffer.clear(bufferSize);

this was based on code from juce_TracktionMarketplaceStatus, it was missing the clear() call, and hence the random rubbish. Unfortunately this occurred just as we were about to release, so completely forgot to report back to @juce team about this one liner addition needed.

I would suspect that your 2nd problem is something to do with not cancelling an ongoing request when issuing multiples.

eg:

request start ---- request finishes ---- request start ---- etc.

is fine, but

request start ---- request start ---- request finishes ---- request finishes

is where your problems lay


#3

The following diff can also be applied to use the HeapBlock (SizeType numElements, bool initialiseToZero) constructor.

--- a/modules/juce_product_unlocking/marketplace/juce_TracktionMarketplaceStatus.cpp
+++ b/modules/juce_product_unlocking/marketplace/juce_TracktionMarketplaceStatus.cpp
@@ -71,7 +71,7 @@ String TracktionMarketplaceStatus::readReplyFromWebserver (const String& email,
         auto downloaded    = 0;

         const size_t bufferSize = 0x8000;
-        HeapBlock<char> buffer (bufferSize);
+        HeapBlock<char> buffer (bufferSize, true);

         while (! (stream->isExhausted() || stream->isError() || thread->threadShouldExit()))
         {

#4

Drat! Thanks for the bug-hunting, I’ll push a fix for that right away!