Skip to content

Conversation

@ghuDaYuYu
Copy link

@ghuDaYuYu ghuDaYuYu commented Sep 6, 2022

First of all thank you so much for providing this library!
I pull this request to share fixes that seam to have solved two issues I encountered.

  • Crash on syntax error:

app. c++

IScriptControlPtr script_control;
_com_util::CheckError(script_control.CreateInstance(__uuidof(ScriptControl)));

try {

	BSTR bsLang = ::SysAllocString(L"JScript");
	script_control->put_Language(bsLang);
	::SysFreeString(bsLang);

	BSTR bsScript = ::SysAllocString(L"function badSyntax() return new Array(0, 1, 2);}");
	script_control->AddCode(bsScript);
	::SysFreeString(bsScript);

} catch (_com_error& e) {

      ::SysFreeString(bsScript);
      rethrow_error(e);
}

The missing bracket in the script triggered either an unhandled exception in jscript.dll or AV exceptions.

Initializing m_pEI inside the CTScriptControl constructor seams to solve it:

CTScriptControl::CTScriptControl()
{
	ITypeLib *pTypeLib;
	m_pEI = NULL;

	...
}

... as this if statement no longer evaluates to true (CTScriptControl::Invoke never runs in my use case?).

STDMETHODIMP CteActiveScriptSite::OnScriptError(IActiveScriptError *pscripterror)
{
	...

	if (m_pSC->m_pEI) {
		try {
			if SUCCEEDED(pscripterror->GetExceptionInfo(m_pSC->m_pEI)) {
				m_pSC->m_hr = DISP_E_EXCEPTION;
			}
		}
		catch (...) {
			m_pSC->m_hr = DISP_E_EXCEPTION;
		}
	}
	...
}

Not sure if this fix may affect other functions like:

HRESULT CTScriptControl::SetScriptError(int n)

Also I have seen that this pull request is related to m_pEI.

  • Crash passing empty argument list to Run function:

app. c++

BSTR bsScript = ::SysAllocString(L"function eyePos() { return new Array(0, 1, 2);	}");
script_control->AddCode(bsScript);
::SysFreeString(bsScript);

...
//lenght is 0 for no arguments
ULONG length = sizeof...(_Args);
CComSafeArray<VARIANT> params{length};

try {
      return Ret(m_script_control->Run(uT(func), params.GetSafeArrayPtr()));
} catch (_com_error& e) {
     if (e.Error() == DISP_E_UNKNOWNNAME) {
       throw script_error(
           PFC_string_formatter() << "Error: Function " << func << "() not found.");
     } else {
        rethrow_error(e);
     }
}

The code runs in 32bit mode but crashes on 64bit.

Issue was solved at first by adding a dummy argument to the parameters, then applied the following modification:

(nArg is set to -1 for empty parameter list)

STDMETHODIMP CTScriptControl::raw_Run(BSTR ProcedureName, SAFEARRAY ** Parameters, VARIANT *pvarResult)
{
	...
	if (*Parameters) {
		::SafeArrayGetUBound(*Parameters, 1, &nArg);
		nArg++;
		if (nArg > 0) {
			pv2 = GetNewVARIANT(nArg);
			...
		}
	}
	...
}

That´s it... thanks again for the great job!

I'll be grateful if you find the time to review this pull request,

Best regards

@ghuDaYuYu ghuDaYuYu changed the title fix unhandled exception (empty arguements and initialized m_pEI) fix unhandled exception (empty arguments and uninitialized m_pEI) Sep 7, 2022
@tablacus tablacus merged commit b61c521 into tablacus:master Sep 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants