Example #1
0
//TODO add input and output values names
std::vector<double> Snakes::calculateOutput(std::vector<double> input, QString scriptFileName)
{
	namespace py = boost::python;

	std::vector<double> output;

	//QString to const char*
	QByteArray byteArray = scriptFileName.toLatin1();
	const char *filename = byteArray.data();

	Py_Initialize();
	py::object main_module = py::import("__main__");
	py::object main_namespace = main_module.attr("__dict__");
	try
	{
		for (int i = 0; i < input.size(); i++)
		{
			main_namespace["inputValue"] = input[i];
			py::object noneType = py::exec_file(filename, main_namespace);
			const double res = py::extract<double>(main_namespace["outputValue"]);
			output.push_back(res);
		}
	}
	catch (...)
	{
		throw ScriptException("Failed to load script");
	}
	return output;
}
Example #2
0
//----------------------------------------------------------------------------//
bool LuaScriptModule::executeScriptedEventHandler_impl(
    const String& handler_name, const EventArgs& e, const int err_idx,
    const int top)
{
    LuaFunctor::pushNamedFunction(d_state, handler_name);

    // push EventArgs as the first parameter
    tolua_pushusertype(d_state, (void*)&e, "const CEGUI::EventArgs");

    // call it
    int error = lua_pcall(d_state, 1, 1, err_idx);

    // handle errors
    if (error)
    {
        String errStr(lua_tostring(d_state,-1));
        lua_settop(d_state,top);

        CEGUI_THROW(ScriptException("Unable to evaluate the Lua event "
            "handler: '" + handler_name + "'\n\n" + errStr + "\n"));
    }

    // retrieve result
    bool ret = lua_isboolean(d_state, -1) ? lua_toboolean(d_state, -1 ) : true;
    lua_settop(d_state,top);

    return ret;
}
Example #3
0
/*************************************************************************
    Call operator
*************************************************************************/
bool LuaFunctor::operator()(const EventArgs& args) const
{
    // named error handler needs binding?
    if ((d_errFuncIndex == LUA_NOREF) && !d_errFuncName.empty())
    {
        pushNamedFunction(L, d_errFuncName);
        d_errFuncIndex = luaL_ref(L, LUA_REGISTRYINDEX);
        d_ourErrFuncIndex = true;
    }

    // is this a late binding?
    if (needs_lookup)
    {
        pushNamedFunction(L, function_name);
        // reference function
        index = luaL_ref(L, LUA_REGISTRYINDEX);
        needs_lookup = false;
        CEGUI_LOGINSANE("Late binding of callback '"+function_name+"' performed");
        function_name.clear();
    }

    // put error handler on stack if we're using such a thing
    int err_idx = 0;
    if (d_errFuncIndex != LUA_NOREF)
    {
        lua_rawgeti(L, LUA_REGISTRYINDEX, d_errFuncIndex);
        err_idx = lua_gettop(L);
    }

    // retrieve function
    lua_rawgeti(L, LUA_REGISTRYINDEX, index);

    // possibly self as well?
    int nargs = 1;
    if (self != LUA_NOREF)
    {
        lua_rawgeti(L, LUA_REGISTRYINDEX, self);
        ++nargs;
    }

    // push EventArgs  parameter
    tolua_pushusertype(L, (void*)&args, "const CEGUI::EventArgs");

    // call it
    int error = lua_pcall(L, nargs, 1, err_idx);

    // handle errors
    if (error)
    {
        String errStr(lua_tostring(L, -1));
        lua_pop(L, 1);
        CEGUI_THROW(ScriptException("Unable to call Lua event handler:\n\n"+errStr+"\n"));
    }

    // retrieve result
    bool ret = lua_isboolean(L, -1) ? lua_toboolean(L, -1 ) : true;
    lua_pop(L, 1);

    return ret;
}
Example #4
0
void StackInterpreter::process_p2wsh(const BinaryData& scriptHash)
{
   //get witness data
   auto witnessData = txStubPtr_->getWitnessData(inputIndex_);
   BinaryData witBD(witnessData);

   //prepare stack
   BinaryRefReader brr(witnessData);
   auto itemCount = brr.get_uint8_t();
   
   for (unsigned i = 0; i < itemCount; i++)
   {
      auto len = brr.get_var_int();
      stack_.push_back(brr.get_BinaryData(len));
   }

   if (brr.getSizeRemaining() != 0)
      throw ScriptException("witness size mismatch");

   flags_ |= SCRIPT_VERIFY_P2SH_SHA256;

   //construct output script
   auto&& swScript = BtcUtils::getP2WSHScript(scriptHash);
   processScript(swScript, true);
}
Example #5
0
bool TransactionVerifier::checkSig(unsigned inputId) const
{
   //grab the uxto
   auto&& input = theTx_.getTxInRef(inputId);
   if (input.getSize() < 41)
      throw ScriptException("unexpected txin size");

   //grab input script
   BinaryRefReader inputBrr(input);
   auto&& txHashRef = inputBrr.get_BinaryDataRef(32);
   auto outputId = inputBrr.get_uint32_t();
   auto scriptSize = inputBrr.get_var_int();
   auto&& inputScript = inputBrr.get_BinaryDataRef(scriptSize);

   auto utxoIter = utxos_.find(txHashRef);
   if (utxoIter == utxos_.end())
      return false;

   auto& idMap = utxoIter->second;
   auto idIter = idMap.find(outputId);
   if (idIter == idMap.end())
      return false;

   //grab output script
   auto& utxo = idIter->second;
   auto& outputScript = utxo.getScript();

   //init stack
   StackInterpreter sstack(this, inputId);
   auto flags = sstack.getFlags();
   flags |= flags_;
   sstack.setFlags(flags);

   if (theTx_.usesWitness_)
   {
      //reuse the sighash data object with segwit tx to leverage the pre state
      if (sigHashDataObject_ == nullptr)
         sigHashDataObject_ = make_shared<SigHashDataSegWit>();

      sstack.setSegWitSigHashDataObject(sigHashDataObject_);
   }

   if ((flags_ & SCRIPT_VERIFY_SEGWIT) &&
      inputScript.getSize() == 0)
   {
      sstack.processSW(outputScript);
   }
   else
   {
      sstack.processScript(inputScript, false);
      BinaryData inputScriptBD(inputScript);

      //process script
      sstack.processScript(outputScript, true);
   }

   sstack.checkState();
   return true;
}
Example #6
0
void StackResolver::resolveStack()
{
   auto resolveReferenceValue = [](
      shared_ptr<ReversedStackEntry> inPtr)->BinaryData
   {
      auto currentPtr = inPtr;
      while (1)
      {
         if (currentPtr->parent_ != nullptr)
         {
            currentPtr = currentPtr->parent_;
         }
         else if (currentPtr->static_)
         {
            return currentPtr->staticData_;
         }
         else
         {
            switch (currentPtr->resolvedValue_->type())
            {
            case StackValueType_Static:
            {
               auto staticVal = dynamic_pointer_cast<StackValue_Static>(
                  currentPtr->resolvedValue_);

               return staticVal->value_;
            }

            case StackValueType_FromFeed:
            {
               auto feedVal = dynamic_pointer_cast<StackValue_FromFeed>(
                  currentPtr->resolvedValue_);

               return feedVal->value_;
            }

            case StackValueType_Reference:
            {
               auto refVal = dynamic_pointer_cast<StackValue_Reference>(
                  currentPtr->resolvedValue_);

               currentPtr = refVal->valueReference_;
               break;
            }

            default:
               throw ScriptException("unexpected StackValue type \
                  during reference resolution");
            }
         }

         if (currentPtr == inPtr)
            throw ScriptException("infinite loop in reference resolution");
      }
   };
Example #7
0
//----------------------------------------------------------------------------//
int LuaScriptModule::executeScriptGlobal_impl(const String& function_name,
    const int err_idx, const int top)
{
    // get the function from lua
    lua_getglobal(d_state, function_name.c_str());

    // is it a function
    if (!lua_isfunction(d_state,-1))
    {
        lua_settop(d_state,top);
        CEGUI_THROW(ScriptException("Unable to get Lua global: '" +
            function_name + "' as name not represent a global Lua function" ));
    }

    // call it
    int error = lua_pcall(d_state, 0, 1, err_idx);

    // handle errors
    if (error)
    {
        String errMsg = lua_tostring(d_state,-1);
        lua_settop(d_state,top);
        CEGUI_THROW(ScriptException("Unable to evaluate Lua global: '" + 
            function_name + "\n\n" + errMsg + "\n"));
    }

    // get return value
    if (!lua_isnumber(d_state,-1))
    {
        // log that return value is invalid. return -1 and move on.
        lua_settop(d_state,top);
        ScriptException("Unable to get Lua global : '" + function_name +
                        "' return value as it's not a number");
        return -1;
    }

    int ret = static_cast<int>(lua_tonumber(d_state,-1));
    lua_settop(d_state,top);

    // return it
    return ret;
}
Example #8
0
float Table::getNumber( int index )
{
    assert( m_ref >= 0 );

    RestoreStack rs( m_lua );
    lua_getref( m_lua, m_ref );
    lua_rawgeti( m_lua, -1, index );
    if ( lua_type(m_lua,-1) != LUA_TNUMBER )
        throw ScriptException( Format("Tried to get number from table but type was invalid ({1})", lua_type(m_lua,-1)) );
    return lua_tonumber( m_lua, -1 );
}
Example #9
0
void* Table::getUserData( int index )
{
    assert( m_ref >= 0 );

    RestoreStack rs( m_lua );
    lua_getref( m_lua, m_ref );
    lua_rawgeti( m_lua, -1, index );
    if ( !lua_isuserdata(m_lua,-1) )
        throw ScriptException( Format("Tried to use script object type({0}) as user data", lua_type(m_lua,-1)) );
    return lua_touserdata( m_lua, -1 );
}
Example #10
0
unsigned TransactionVerifier::getTxInSequence(unsigned inputID) const
{
   if (inputID > theTx_.txins_.size())
      throw ScriptException("invalid txin index");

   auto& inputOnS = theTx_.txins_[inputID];
   auto sequenceOffset = inputOnS.first + inputOnS.second - 4;

   auto sequence = (unsigned*)(theTx_.data_ + sequenceOffset);
   return *sequence;
}
Example #11
0
float Table::getNumber( const String& name )
{
    assert( m_ref >= 0 );

    RestoreStack rs( m_lua );
    lua_getref( m_lua, m_ref );
    lua_pushUTF8( m_lua, name );
    lua_rawget( m_lua, -2 );
    if ( lua_type(m_lua,-1) != LUA_TNUMBER )
        throw ScriptException( Format("Tried to get number {0} from table but type was invalid ({1})", name, lua_type(m_lua,-1)) );
    return lua_tonumber( m_lua, -1 );
}
Example #12
0
bool Table::getBoolean( const String& name )
{
    assert( m_ref >= 0 );

    RestoreStack rs( m_lua );
    lua_getref( m_lua, m_ref );
    lua_pushUTF8( m_lua, name );
    lua_rawget( m_lua, -2 );
    if ( lua_type(m_lua,-1) != LUA_TNUMBER && !lua_isnil(m_lua,-1) )
        throw ScriptException( Format("Tried to get boolean {0} from table but type was invalid ({1})", name, lua_type(m_lua,-1)) );
    return !lua_isnil( m_lua, -1 );
}
Example #13
0
void* Table::getUserData( const String& name )
{
    assert( m_ref >= 0 );

    RestoreStack rs( m_lua );
    lua_getref( m_lua, m_ref );
    lua_pushUTF8( m_lua, name );
    lua_rawget( m_lua, -2 );
    if ( !lua_isuserdata(m_lua,-1) )
        throw ScriptException( Format("Tried to use script object {0} type({1}) as user data", name, lua_type(m_lua,-1)) );
    return lua_touserdata( m_lua, -1 );
}
Example #14
0
void StackInterpreter::op_checksig()
{
   //pop sig and pubkey from the stack
   if (stack_.size() < 2)
      throw ScriptException("insufficient stack size for checksig operation");

   auto&& pubkey = pop_back();
   auto&& sigScript = pop_back();
   if (sigScript.getSize() < 65)
   {
      stack_.push_back(move(intToRawBinary(false)));
      return;
   }

   txInEvalState_.n_ = 1;
   txInEvalState_.m_ = 1;

   //extract sig and sighash type
   BinaryRefReader brrSig(sigScript);
   auto sigsize = sigScript.getSize() - 1;
   auto sig = brrSig.get_BinaryDataRef(sigsize);
   auto hashType = getSigHashSingleByte(brrSig.get_uint8_t());

   //get data for sighash
   if (sigHashDataObject_ == nullptr)
      sigHashDataObject_ = make_shared<SigHashDataLegacy>();
   auto&& sighashdata =
      sigHashDataObject_->getDataForSigHash(hashType, *txStubPtr_,
      outputScriptRef_, inputIndex_);

   //prepare pubkey
   BTC_ECPOINT ptPub;
   CryptoPP::ECP ecp = CryptoECDSA::Get_secp256k1_ECP();
   ecp.DecodePoint(ptPub, (byte*)pubkey.getPtr(), pubkey.getSize());

   BTC_PUBKEY cppPubKey;
   cppPubKey.Initialize(CryptoPP::ASN1::secp256k1(), ptPub);

   //check point validity
   /*BTC_PRNG prng;
   if (!cppPubKey.Validate(prng, 3))
   throw ScriptException("invalid pubkey");*/

   //check signature
   auto&& rs = BtcUtils::extractRSFromDERSig(sig);

   bool result = CryptoECDSA().VerifyData(sighashdata, rs, cppPubKey);
   stack_.push_back(move(intToRawBinary(result)));

   if (result)
      txInEvalState_.pubKeyState_.insert(make_pair(pubkey, true));
}
void handleException(TryCatch& tc)
{
    Logging::log(Logging::ERROR, "V8 exception:\r\n");

    HandleScope handleScope;

    Handle<Object> exception = tc.Exception()->ToObject();
    String::AsciiValue exception_str(exception);

    Logging::log(Logging::ERROR, "            : %s\r\n", *exception_str);

/*
    Handle<Array> names = exception->GetPropertyNames();
    for (unsigned int i = 0; i < names->Length(); i++)
    {
        std::string strI = Utility::toString((int)i);
        Logging::log(Logging::ERROR, "    %d : %s : %s\r\n", i,
            *(v8::String::Utf8Value(names->Get(String::New(strI.c_str()))->ToString())),
            *(v8::String::Utf8Value(exception->Get(names->Get(String::New(strI.c_str()))->ToString())->ToString()))
        );
    }
*/

    Local<Message> message = tc.Message();

    Logging::log(Logging::ERROR, "Message: Get: %s\r\n", *(v8::String::Utf8Value( message->Get() )));
    Logging::log(Logging::ERROR, "Message: GetSourceLine: %s\r\n", *(v8::String::Utf8Value( message->GetSourceLine() )));
    Logging::log(Logging::ERROR, "Message: GetScriptResourceName: %s\r\n", *(v8::String::Utf8Value( message->GetScriptResourceName()->ToString() )));
    Logging::log(Logging::ERROR, "Message: GetLineNumber: %d\r\n", message->GetLineNumber() );

    Local<Value> stackTrace = tc.StackTrace();
    if (!stackTrace.IsEmpty())
    {
        Logging::log(Logging::ERROR, "Stack trace: %s\r\n", *(v8::String::Utf8Value( stackTrace->ToString() )));
        printf("\r\n\r\n^Stack trace^: %s\r\n", *(v8::String::Utf8Value( stackTrace->ToString() )));
    }
    else
        Logging::log(Logging::ERROR, "No stack trace available in C++ handler (see above for possible in-script stack trace)\r\n");

    #ifdef SERVER
        std::string clientMessage = *(v8::String::Utf8Value( message->Get() ));
        clientMessage += "  -  ";
        clientMessage += *(v8::String::Utf8Value( message->GetSourceLine() ));
        ServerSystem::fatalMessageToClients(clientMessage);
    #endif

//    assert(0);
    throw ScriptException("Bad!");
}
Example #16
0
Table Table::getTable( int index )
{
    assert( m_ref >= 0 );

    RestoreStack rs( m_lua );
    lua_getref( m_lua, m_ref );
    lua_rawgeti( m_lua, -1, index );
    if ( !lua_istable(m_lua,-1) )
        throw ScriptException( Format("Tried to get table from table but type was invalid ({1})", lua_type(m_lua,-1)) );

    Table tab;
    tab.m_lua = m_lua;
    tab.m_ref = lua_ref( m_lua, true );
    return tab;
}
Example #17
0
Table Table::getTable( const String& name )
{
    assert( m_ref >= 0 );

    RestoreStack rs( m_lua );
    lua_getref( m_lua, m_ref );
    lua_pushUTF8( m_lua, name );
    lua_rawget( m_lua, -2 );
    if ( !lua_istable(m_lua,-1) )
        throw ScriptException( Format("Tried to get table {0} from table but type was invalid ({1})", name, lua_type(m_lua,-1)) );

    Table tab;
    tab.m_lua = m_lua;
    tab.m_ref = lua_ref( m_lua, true );
    return tab;
}
Example #18
0
//----------------------------------------------------------------------------//
void LuaScriptModule::executeString_impl(const String& str, const int err_idx,
    const int top)
{
    // load code into lua and call it
    int error = luaL_loadbuffer(d_state, str.c_str(), str.length(), str.c_str()) ||
                lua_pcall(d_state, 0, 0, err_idx);

    // handle errors
    if (error)
    {
        String errMsg = lua_tostring(d_state,-1);
        lua_settop(d_state,top);
        CEGUI_THROW(ScriptException("Unable to execute Lua script string: '" +
            str + "'\n\n" + errMsg + "\n"));
    }

    lua_settop(d_state,top);
}
Example #19
0
void StackInterpreter::processOpCode(const OpCode& oc)
{
   ++opcount_;

   //handle push data by itself, doesn't play well with switch
   if (oc.opcode_ == 0)
   {
      op_0();
      return;
   }

   if (oc.opcode_ <= 75)
   {
      stack_.push_back(oc.dataRef_);
      return;
   }

   if (oc.opcode_ < 79)
   {
      //op push data
      stack_.push_back(oc.dataRef_);
      return;
   }

   if (oc.opcode_ == OP_1NEGATE)
   {
      op_1negate();
      return;
   }

   if (oc.opcode_ <= 96 && oc.opcode_ >= 81)
   {
      //op_1 - op_16
      uint8_t val = oc.opcode_ - 80;
      stack_.push_back(move(intToRawBinary(val)));
      return;
   }

   //If we got this far this op code is not push data. If this is the input
   //script, set the flag as per P2SH parsing rules (only push data in inputs)
   if (outputScriptRef_.getSize() == 0)
      onlyPushDataInInput_ = false;

   switch (oc.opcode_)
   {
   case OP_NOP:
      break;

   case OP_IF:
   {
      BinaryRefReader brr(oc.dataRef_);
      op_if(brr, false);
      break;
   }

   case OP_NOTIF:
   {
      op_not();
      BinaryRefReader brr(oc.dataRef_);
      op_if(brr, false);
      break;
   }

   case OP_ELSE:
      //processed by opening if statement
      throw ScriptException("a wild else appears");

   case OP_ENDIF:
      //processed by opening if statement
      throw ScriptException("a wild endif appears");

   case OP_VERIFY:
      op_verify();
      break;

   case OP_TOALTSTACK:
      op_toaltstack();
      break;

   case OP_FROMALTSTACK:
      op_fromaltstack();
      break;

   case OP_IFDUP:
      op_ifdup();
      break;

   case OP_2DROP:
   {
      stack_.pop_back();
      stack_.pop_back();
      break;
   }

   case OP_2DUP:
      op_2dup();
      break;

   case OP_3DUP:
      op_3dup();
      break;

   case OP_2OVER:
      op_2over();
      break;

   case OP_DEPTH:
      op_depth();
      break;

   case OP_DROP:
      stack_.pop_back();
      break;

   case OP_DUP:
      op_dup();
      break;

   case OP_NIP:
      op_nip();
      break;

   case OP_OVER:
      op_over();
      break;

   case OP_PICK:
      op_pick();
      break;

   case OP_ROLL:
      op_roll();
      break;

   case OP_ROT:
      op_rot();
      break;

   case OP_SWAP:
      op_swap();
      break;

   case OP_TUCK:
      op_tuck();
      break;

   case OP_SIZE:
      op_size();
      break;

   case OP_EQUAL:
   {
      op_equal();
      if (onlyPushDataInInput_ && p2shScript_.getSize() != 0)
      {
         //check the op_equal result
         op_verify();
         if (!isValid_)
            break;

         if (flags_ & SCRIPT_VERIFY_SEGWIT)
            if (p2shScript_.getSize() == 22 ||
               p2shScript_.getSize() == 34)
            {
               auto versionByte = p2shScript_.getPtr();
               if (*versionByte <= 16)
               {
                  processSW(p2shScript_);
                  return;
               }
            }

         processScript(p2shScript_, true);
      }
      break;
   }

   case OP_EQUALVERIFY:
   {
      op_equal();
      op_verify();
      break;
   }

   case OP_1ADD:
      op_1add();
      break;

   case OP_1SUB:
      op_1sub();
      break;

   case OP_NEGATE:
      op_negate();
      break;

   case OP_ABS:
      op_abs();
      break;

   case OP_NOT:
      op_not();
      break;

   case OP_0NOTEQUAL:
      op_0notequal();
      break;

   case OP_ADD:
      op_add();
      break;

   case OP_SUB:
      op_sub();
      break;

   case OP_BOOLAND:
      op_booland();
      break;

   case OP_BOOLOR:
      op_boolor();
      break;

   case OP_NUMEQUAL:
      op_numequal();
      break;

   case OP_NUMEQUALVERIFY:
   {
      op_numequal();
      op_verify();
      break;
   }

   case OP_NUMNOTEQUAL:
      op_numnotequal();
      break;

   case OP_LESSTHAN:
      op_lessthan();
      break;

   case OP_GREATERTHAN:
      op_greaterthan();
      break;

   case OP_LESSTHANOREQUAL:
      op_lessthanorequal();
      break;

   case OP_GREATERTHANOREQUAL:
      op_greaterthanorequal();
      break;

   case OP_MIN:
      op_min();
      break;

   case OP_MAX:
      op_max();
      break;

   case OP_WITHIN:
      op_within();
      break;

   case OP_RIPEMD160:
      op_ripemd160();
      break;

   case OP_SHA256:
   {
      //save the script if this output is a possible p2sh
      if (flags_ & SCRIPT_VERIFY_P2SH_SHA256)
         if (opcount_ == 1 && onlyPushDataInInput_)
            p2shScript_ = stack_back();

      op_sha256();
      break;
   }

   case OP_HASH160:
   {
      //save the script if this output is a possible p2sh
      if (flags_ & SCRIPT_VERIFY_P2SH)
         if (opcount_ == 1 && onlyPushDataInInput_)
            p2shScript_ = stack_back();

      op_hash160();
      break;
   }

   case OP_HASH256:
      op_hash256();
      break;

   case OP_CODESEPARATOR:
   {
      opcount_ = 0;
      if (outputScriptRef_.getSize() != 0)
         txStubPtr_->setLastOpCodeSeparator(inputIndex_, oc.offset_);
      break;
   }

   case OP_CHECKSIG:
      op_checksig();
      break;

   case OP_CHECKSIGVERIFY:
   {
      op_checksig();
      op_verify();
      break;
   }

   case OP_CHECKMULTISIG:
      op_checkmultisig();
      break;

   case OP_CHECKMULTISIGVERIFY:
   {
      op_checkmultisig();
      op_verify();
   }

   case OP_NOP1:
      break;

   case OP_NOP2:
   {
      if (!(flags_ & SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY))
         break; // not enabled; treat as a NOP

      //CLTV mechanics
      throw ScriptException("OP_CLTV not supported");
   }

   case OP_NOP3:
   {
      if (!(flags_ & SCRIPT_VERIFY_CHECKSEQUENCEVERIFY))
         break; // not enabled; treat as a NOP

      //CSV mechanics
      throw ScriptException("OP_CSV not supported");
   }

   case OP_NOP4:
      break;

   case OP_NOP5:
      break;

   case OP_NOP6:
      break;

   case OP_NOP7:
      break;

   case OP_NOP8:
      break;

   case OP_NOP9:
      break;

   case OP_NOP10:
      break;

   default:
   {
      stringstream ss;
      ss << "unknown opcode: " << (unsigned)oc.opcode_;
      throw runtime_error(ss.str());
   }
   }
}
Example #20
0
/*************************************************************************
    Pushes a named function on the stack
*************************************************************************/
void LuaFunctor::pushNamedFunction(lua_State* L, const String& handler_name)
{
    int top = lua_gettop(L);

    // do we have any dots in the handler name? if so we grab the function as a table field
    String::size_type i = handler_name.find_first_of((utf32)'.');
    if (i!=String::npos)
    {
        // split the rest of the string up in parts seperated by '.'
        // TODO: count the dots and size the vector accordingly from the beginning.
        std::vector<String> parts;
        String::size_type start = 0;
        do
        {
            parts.push_back(handler_name.substr(start,i-start));
            start = i+1;
            i = handler_name.find_first_of((utf32)'.',start);
        } while(i!=String::npos);

        // add last part
        parts.push_back(handler_name.substr(start));

        // first part is the global
        lua_getglobal(L, parts[0].c_str());
        if (!lua_istable(L,-1))
        {
            lua_settop(L,top);
            CEGUI_THROW(ScriptException("Unable to get the Lua event handler: '"+handler_name+"' as first part is not a table"));
        }

        // if there is more than two parts, we have more tables to go through
        std::vector<String>::size_type visz = parts.size();
        if (visz-- > 2) // avoid subtracting one later on
        {
            // go through all the remaining parts to (hopefully) have a valid Lua function in the end
            std::vector<String>::size_type vi = 1;
            while (vi<visz)
            {
                // push key, and get the next table
                lua_pushstring(L,parts[vi].c_str());
                lua_gettable(L,-2);
                if (!lua_istable(L,-1))
                {
                    lua_settop(L,top);
                    CEGUI_THROW(ScriptException("Unable to get the Lua event handler: '"+handler_name+"' as part #"+PropertyHelper::uintToString(uint(vi+1))+" ("+parts[vi]+") is not a table"));
                }
                // get rid of the last table and move on
                lua_remove(L,-2);
                vi++;
            }
        }

        // now we are ready to get the function to call ... phew :)
        lua_pushstring(L,parts[visz].c_str());
        lua_gettable(L,-2);
        lua_remove(L,-2); // get rid of the table
    }
    // just a regular global function
    else
    {
        lua_getglobal(L, handler_name.c_str());
    }

    // is it a function
    if (!lua_isfunction(L,-1))
    {
        lua_settop(L,top);
        CEGUI_THROW(ScriptException("The Lua event handler: '"+handler_name+"' does not represent a Lua function"));
    }
}
Example #21
0
void StackResolver::processOpCode(const OpCode& oc)
{
   if (oc.opcode_ >= 1 && oc.opcode_ <= 75)
   {
      pushdata(oc.dataRef_);
      return;
   }

   if (oc.opcode_ >= 81 && oc.opcode_ <= 96)
   {
      unsigned val = oc.opcode_ - 80;
      push_int(val);
      return;
   }

   opCodeCount_++;
   switch (oc.opcode_)
   {
   case OP_0:
      pushdata(BinaryData());
      break;

   case OP_PUSHDATA1:
   case OP_PUSHDATA2:
   case OP_PUSHDATA4:
      pushdata(oc.dataRef_);
      break;

   case OP_DUP:
      op_dup();
      break;

   case OP_HASH160:
   case OP_SHA256:
   {
      opHash_ = true;
      op_1item_verify(oc);
      break;
   }

   case OP_RIPEMD160:
   case OP_HASH256:
      op_1item_verify(oc);
      break;

   case OP_EQUAL:
   {
      if (opCodeCount_ == 2 && opHash_)
         isP2SH_ = true;
      op_2items(oc);
      break;
   }

   case OP_CHECKSIG:
      op_2items(oc);
      break;

   case OP_EQUALVERIFY:
   case OP_CHECKSIGVERIFY:
      op_2items_verify(oc);
      break;

   case OP_CHECKMULTISIG:
   case OP_CHECKMULTISIGVERIFY:
      push_op_code(oc);
      break;

   default:
      throw ScriptException("opcode not implemented with reverse stack");
   }
}
Example #22
0
SIGHASH_TYPE StackInterpreter_BCH::getSigHashSingleByte(uint8_t sighashbyte) const
{
   if (!(sighashbyte & 0x40))
      throw ScriptException("invalid sighash for bch sig");
   return SIGHASH_TYPE(sighashbyte & 0xBF);
}
Example #23
0
void StackInterpreter::op_checkmultisig()
{
   //stack needs to have at least m, n, output script
   if (stack_.size() < 3)
      throw ScriptException("insufficient stack size for checkmultisig operation");

   //pop n
   auto&& n = pop_back();
   auto nI = rawBinaryToInt(n);
   if (nI < 0 || nI > 20)
      throw ScriptException("invalid n");

   //pop pubkeys
   map<unsigned, pair<BTC_PUBKEY, BinaryData>> pubkeys;
   for (unsigned i = 0; i < nI; i++)
   {
      auto&& pubkey = pop_back();

      CryptoPP::ECP ecp = CryptoECDSA::Get_secp256k1_ECP();
      BTC_ECPOINT ptPub;
      ecp.DecodePoint(ptPub, (byte*)pubkey.getPtr(), pubkey.getSize());

      BTC_PUBKEY cppPubKey;
      cppPubKey.Initialize(CryptoPP::ASN1::secp256k1(), ptPub);

      BTC_PRNG prng;
      if (cppPubKey.Validate(prng, 3))
      {
         txInEvalState_.pubKeyState_.insert(make_pair(pubkey, false));
         auto&& pubkeypair = make_pair(move(cppPubKey), pubkey);
         pubkeys.insert(move(make_pair(i, move(pubkeypair))));
      }
   }

   //pop m
   auto&& m = pop_back();
   auto mI = rawBinaryToInt(m);
   if (mI < 0 || mI > nI)
      throw ScriptException("invalid m");

   txInEvalState_.n_ = nI;
   txInEvalState_.m_ = mI;

   //pop sigs
   struct sigData
   {
      BinaryData sig_;
      SIGHASH_TYPE hashType_;
   };
   vector<sigData> sigVec;

   while (stack_.size() > 0)
   {
      auto&& sig = pop_back();
      if (sig.getSize() == 0)
         break;

      sigData sdata;

      sdata.sig_ = sig.getSliceCopy(0, sig.getSize() - 1);

      //grab hash type
      sdata.hashType_ = 
         getSigHashSingleByte(*(sig.getPtr() + sig.getSize() - 1));

      //push to vector
      sigVec.push_back(move(sdata));
   }

   //should have at least as many sigs as m
   /*if (sigVec.size() < mI)
      throw ScriptException("invalid sig count");*/

   //check sigs
   map<SIGHASH_TYPE, BinaryData> dataToHash;

   //check sighashdata object
   if (sigHashDataObject_ == nullptr)
      sigHashDataObject_ = make_shared<SigHashDataLegacy>();

   unsigned validSigCount = 0;
   int index = nI - 1;
   auto sigIter = sigVec.rbegin();
   while(sigIter != sigVec.rend())
   {
      auto& sigD = *sigIter++;

      //get data to hash
      auto& hashdata = dataToHash[sigD.hashType_];
      if (hashdata.getSize() == 0)
      {
         hashdata = sigHashDataObject_->getDataForSigHash(
            sigD.hashType_, *txStubPtr_, outputScriptRef_, inputIndex_);
      }

      //prepare sig
      auto&& rs = BtcUtils::extractRSFromDERSig(sigD.sig_);
      BinaryWriter sigW;

      //pop pubkeys from deque to verify against sig
      while (pubkeys.size() > 0)
      {
         auto pubkey = pubkeys[index];
         pubkeys.erase(index--);

#ifdef SIGNER_DEBUG
         LOGWARN << "Verifying sig for: ";
         LOGWARN << "   pubkey: " << pubkey.second.toHexStr();

         auto&& msg_hash = BtcUtils::getHash256(hashdata);
         LOGWARN << "   message: " << hashdata.toHexStr();
#endif
            
         if (CryptoECDSA().VerifyData(hashdata, rs, pubkey.first))
         {
            txInEvalState_.pubKeyState_[pubkey.second] = true;
            validSigCount++;
            break;
         }        
      }
   }

   if (validSigCount >= mI)
      op_true();
   else
      op_0();
}