diff Framework/Oracle/WebAssemblyOracle.cpp @ 975:e75fd08d6c75 toa2019083101

Cleaning in ICallable + changed fingerprint to plain char array to allow for dead object examination + additional check in FetchContext callback to avoid the unexplained rogue callbacks I have seen + protection in LoaderStateMachine::HandleSuccessMessage in case things go wrong anyway
author Benjamin Golinvaux <bgo@osimis.io>
date Sat, 31 Aug 2019 13:45:04 +0200
parents 38409549db43
children 262a0244e9b2
line wrap: on
line diff
--- a/Framework/Oracle/WebAssemblyOracle.cpp	Thu Aug 29 18:08:48 2019 +0200
+++ b/Framework/Oracle/WebAssemblyOracle.cpp	Sat Aug 31 13:45:04 2019 +0200
@@ -99,7 +99,6 @@
   private:
     Emitter                        emitter_;
     const IObserver&               receiver_;
-    std::string                    receiverFingerprint_;
     std::auto_ptr<IOracleCommand>  command_;
     std::string                    expectedContentType_;
 
@@ -110,7 +109,6 @@
                  const std::string& expectedContentType) :
       emitter_(oracle),
       receiver_(receiver),
-      receiverFingerprint_(receiver.GetFingerprint()),
       command_(command),
       expectedContentType_(expectedContentType)
     {
@@ -120,16 +118,6 @@
       }
     }
 
-    bool IsFingerprintOK() const
-    {
-      bool ok = receiverFingerprint_ == receiver_.GetFingerprint();
-      if (!ok)
-      {
-        LOG(TRACE) << "IsFingerprintOK returned false. receiverFingerprint_ = " << receiverFingerprint_ << " | receiver_(" << std::hex << (&receiver_) << std::dec << ").GetFingerprint() = " << receiver_.GetFingerprint();
-      }
-      return ok;
-    }
-
     const std::string& GetExpectedContentType() const
     {
       return expectedContentType_;
@@ -208,6 +196,18 @@
       
       std::auto_ptr<FetchContext> context(reinterpret_cast<FetchContext*>(fetch->userData));
 
+      // an UUID is 36 chars : 32 hex chars + 4 hyphens: char #0 --> char #35
+      // char #36 is \0.
+      
+      // TODO: remove this line because we are NOT allowed to call methods on GetReceiver that is maybe a dangling ref
+      if (context->GetReceiver().DoesFingerprintLookGood()) {
+        LOG(TRACE) << "SuccessCallback for object at address (" << std::hex << &(context->GetReceiver()) << std::dec << " with current fingerprint = " << context->GetReceiver().GetFingerprint();
+      }
+      else {
+        LOG(TRACE) << "SuccessCallback for object at address (" << std::hex << &(context->GetReceiver()) << std::dec << " with current fingerprint is XXXXX -- NOT A VALID FINGERPRINT! OBJECT IS READ ! CALLBACK WILL NOT BE CALLED!";
+      }
+      
+
       if (fetch->userData == NULL)
       {
         LOG(ERROR) << "WebAssemblyOracle::FetchContext::SuccessCallback fetch->userData is NULL!!!!!!!";
@@ -243,27 +243,25 @@
         DumpCommand(fetch, answer);
       }
 #endif
+      LOG(TRACE) << "About to call emscripten_fetch_close";
       emscripten_fetch_close(fetch);
+      LOG(TRACE) << "Successfully called emscripten_fetch_close";
 
       /**
        * Secondly, use the retrieved data.
-       * We only use the receiver if its fingerprint matches the one stored
-       * at command creation. 
+       * IMPORTANT NOTE: the receiver might be dead. This is prevented 
+       * by the object responsible for zombie check, later on.
        **/
-      if (!context->IsFingerprintOK())
-      {
-        LOG(WARNING) << "FetchContext::SuccessCallback -- the initial request initiator has been destroyed. Response will be discarded.";
-      }
-      else
+      try
       {
-        try
+        if (context.get() == NULL)
         {
-          if (context.get() == NULL)
-          {
-            throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);
-          }
-          else
-          {
+          LOG(ERROR) << "WebAssemblyOracle::FetchContext::SuccessCallback: (context.get() == NULL)";
+          throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);
+        }
+        else
+        {
+          if (context->GetReceiver().DoesFingerprintLookGood()) {
             switch (context->GetCommand().GetType())
             {
             case IOracleCommand::Type_OrthancRestApi:
@@ -294,10 +292,10 @@
             }
           }
         }
-        catch (Orthanc::OrthancException& e)
-        {
-          LOG(ERROR) << "Error while processing a fetch answer in the oracle: " << e.What();
-        }
+      }
+      catch (Orthanc::OrthancException& e)
+      {
+        LOG(ERROR) << "Error while processing a fetch answer in the oracle: " << e.What();
       }
     }