CVE-2023-30186 (published 2023-08-14T13:15Z)

A use after free issue discovered in ONLYOFFICE DocumentServer 4.0.3 through 7.3.2 allows remote attackers to run arbitrary code via crafted JavaScript file.

CVSS v3 base score: 9.8, CRITICAL (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-416
cwe_name: Use After Free
description: The product reuses or references memory after it has been freed. At some point afterward, the memory may be allocated again and saved in another pointer, while the original pointer references a location somewhere within the new allocation. Any operations using the original pointer are no longer valid because the memory "belongs" to the code that operates on the new pointer.
extended_description: 
             
             
             
			 
             
             
         
         

Fix information:
repo_url: https://github.com/ONLYOFFICE/core
commit_details: repo_url: https://github.com/ONLYOFFICE/core
author: Oleg Korshul
author_date: 2023-02-04 23:49:41+03:00
msg: Fix bug 60433
repository: repo_url: https://github.com/ONLYOFFICE/core
repo_name: ONLYOFFICE/core
description: Server core components which are a part of ONLYOFFICE Document Server
repo_language: C++
owner: ONLYOFFICE
file_changes: filename: docbuilder_p.cpp
change_type: ModificationType.MODIFY
diff: @@ -76,8 +76,8 @@ bool CV8RealTimeWorker::ExecuteCommand(const std::wstring& command, NSDoctRender
 {
 	LOGGER_SPEED_START
 
-			if (retValue)
-			retValue->Clear();
+	if (retValue)
+		retValue->Clear();
 
 	std::string commandA = U_TO_UTF8(command);
 	//commandA = "Api." + commandA;
@@ -87,7 +87,7 @@ bool CV8RealTimeWorker::ExecuteCommand(const std::wstring& command, NSDoctRender
 
 	LOGGER_SPEED_LAP("compile_command")
 
-			JSSmart<CJSValue> retNativeVal = m_context->runScript(commandA, try_catch);
+	JSSmart<CJSValue> retNativeVal = m_context->runScript(commandA, try_catch);
 	if(try_catch->Check())
 		return false;
 
@@ -100,7 +100,7 @@ bool CV8RealTimeWorker::ExecuteCommand(const std::wstring& command, NSDoctRender
 
 	LOGGER_SPEED_LAP("run_command")
 
-			return true;
+	return true;
 }
 
 std::string CV8RealTimeWorker::GetGlobalVariable()
@@ -139,7 +139,7 @@ bool CV8RealTimeWorker::OpenFile(const std::wstring& sBasePath, const std::wstri
 {
 	LOGGER_SPEED_START
 
-			JSSmart<CJSContextScope> context_scope = m_context->CreateContextScope();
+	JSSmart<CJSContextScope> context_scope = m_context->CreateContextScope();
 	JSSmart<CJSTryCatch>         try_catch = m_context->GetExceptions();
 
 	LOGGER_SPEED_LAP("compile");
@@ -150,7 +150,7 @@ bool CV8RealTimeWorker::OpenFile(const std::wstring& sBasePath, const std::wstri
 
 	LOGGER_SPEED_LAP("run")
 
-			if (true)
+	if (true)
 	{
 		std::string sArg = m_sUtf8ArgumentJSON;
 		if (sArg.empty())
@@ -249,7 +249,7 @@ bool CV8RealTimeWorker::OpenFile(const std::wstring& sBasePath, const std::wstri
 
 	LOGGER_SPEED_LAP("open")
 
-			return !bIsBreak;
+	return !bIsBreak;
 }
 
 bool CV8RealTimeWorker::SaveFileWithChanges(int type, const std::wstring& _path, const std::wstring& sJsonParams)

programming_language: C++
filename: docbuilder_p.h
change_type: ModificationType.MODIFY
diff: @@ -890,7 +890,7 @@ namespace NSDoctRenderer
 
 			LOGGER_SPEED_START
 
-					CheckFileDir();
+			CheckFileDir();
 			NSDirectory::CreateDirectory(m_sFileDir + L"/changes");
 
 			std::wstring sExtCopy = GetFileCopyExt(path);
@@ -912,8 +912,8 @@ namespace NSDoctRenderer
 
 			LOGGER_SPEED_LAP("open_convert")
 
-					if (0 == nReturnCode)
-					return 0;
+			if (0 == nReturnCode)
+				return 0;
 
 			NSDirectory::DeleteDirectory(m_sFileDir);
 			m_sFileDir = L"";

programming_language: C++
filename: jsc_NativeControl.mm
change_type: ModificationType.MODIFY
diff: @@ -14,8 +14,8 @@
 -(JSValue*) CheckNextChange;
 -(JSValue*) GetCountChanges;
 -(JSValue*) GetChangesFile : (JSValue*)index;
--(JSValue*) Save_AllocNative : (JSValue*)len;
--(JSValue*) Save_ReAllocNative : (JSValue*)pos : (JSValue*)len;
+//-(JSValue*) Save_AllocNative : (JSValue*)len;
+//-(JSValue*) Save_ReAllocNative : (JSValue*)pos : (JSValue*)len;
 -(JSValue*) Save_End : (JSValue*)pos : (JSValue*)len;
 -(JSValue*) AddImageInChanges : (JSValue*)img;
 -(JSValue*) ConsoleLog : (JSValue*)message;
@@ -54,8 +54,8 @@ FUNCTION_WRAPPER_JS(GetEditorType, GetEditorType)
 FUNCTION_WRAPPER_JS(CheckNextChange, CheckNextChange)
 FUNCTION_WRAPPER_JS(GetCountChanges, GetCountChanges)
 FUNCTION_WRAPPER_JS_1(GetChangesFile, GetChangesFile)
-FUNCTION_WRAPPER_JS_1(Save_AllocNative, Save_AllocNative)
-FUNCTION_WRAPPER_JS_2(Save_ReAllocNative, Save_ReAllocNative)
+//FUNCTION_WRAPPER_JS_1(Save_AllocNative, Save_AllocNative)
+//FUNCTION_WRAPPER_JS_2(Save_ReAllocNative, Save_ReAllocNative)
 FUNCTION_WRAPPER_JS_2(Save_End, Save_End)
 FUNCTION_WRAPPER_JS_1(AddImageInChanges, AddImageInChanges)
 FUNCTION_WRAPPER_JS_1(ConsoleLog, ConsoleLog)

programming_language: Objective-C
filename: v8_NativeControl.cpp
change_type: ModificationType.MODIFY
diff: @@ -3,147 +3,159 @@
 
 namespace NSNativeControl
 {
-    #define CURRENTWRAPPER CNativeControlEmbed
-
-    FUNCTION_WRAPPER_V8(_GetFilePath, GetFilePath)
-    FUNCTION_WRAPPER_V8_1(_SetFilePath, SetFilePath)
-    FUNCTION_WRAPPER_V8(_GetFileId, GetFileId)
-    FUNCTION_WRAPPER_V8_1(_SetFileId, SetFileId)
-    FUNCTION_WRAPPER_V8_1(_GetFileArrayBuffer, GetFileBinary)
-    FUNCTION_WRAPPER_V8_1(_GetFontArrayBuffer, GetFontBinary)
-    FUNCTION_WRAPPER_V8(_GetFontsDirectory, GetFontsDirectory)
-    FUNCTION_WRAPPER_V8_1(_GetFileString, GetFileString)
-    FUNCTION_WRAPPER_V8(_GetEditorType, GetEditorType)
-    FUNCTION_WRAPPER_V8(_CheckNextChange, CheckNextChange)
-    FUNCTION_WRAPPER_V8(_GetChangesCount, GetCountChanges)
-    FUNCTION_WRAPPER_V8_1(_GetChangesFile, GetChangesFile)
-    FUNCTION_WRAPPER_V8_1(_Save_AllocNative, Save_AllocNative)
-    FUNCTION_WRAPPER_V8_2(_Save_ReAllocNative, Save_ReAllocNative)
-    FUNCTION_WRAPPER_V8_2(_Save_End, Save_End)
-    FUNCTION_WRAPPER_V8_1(_AddImageInChanges, AddImageInChanges)
-    FUNCTION_WRAPPER_V8_1(_ConsoleLog, ConsoleLog)
-    FUNCTION_WRAPPER_V8_3(_SaveChanges, SaveChanges)
-    FUNCTION_WRAPPER_V8_1(_zipOpenFile, zipOpenFile)
-    FUNCTION_WRAPPER_V8_1(_zipOpenFileBase64, zipOpenFileBase64)
-    FUNCTION_WRAPPER_V8_1(_zipGetFileAsString, zipGetFileAsString)
-    FUNCTION_WRAPPER_V8_1(_zipGetFileAsBinary, zipGetFileAsBinary)
-    FUNCTION_WRAPPER_V8(_zipCloseFile, zipCloseFile)
-    FUNCTION_WRAPPER_V8_1(_GetImageUrl, GetImageUrl)
-    FUNCTION_WRAPPER_V8_1(_GetImageOriginalSize, GetImageOriginalSize)
-    FUNCTION_WRAPPER_V8(_GetImagesPath, GetImagesPath)
-
-    v8::Handle<v8::ObjectTemplate> CreateNativeControlTemplate(v8::Isolate* isolate)
-    {
-        v8::EscapableHandleScope handle_scope(isolate);
-
-        v8::Local<v8::ObjectTemplate> result = v8::ObjectTemplate::New(V8IsolateOneArg);
-        result->SetInternalFieldCount(1);
-
-        NSV8Objects::Template_Set(result, "SetFilePath",        _SetFilePath);
-        NSV8Objects::Template_Set(result, "GetFilePath",        _GetFilePath);
-        NSV8Objects::Template_Set(result, "SetFileId",          _SetFileId);
-        NSV8Objects::Template_Set(result, "GetFileId",          _GetFileId);
-        NSV8Objects::Template_Set(result, "GetFileBinary",      _GetFileArrayBuffer);
-        NSV8Objects::Template_Set(result, "GetFontBinary",      _GetFontArrayBuffer);
-        NSV8Objects::Template_Set(result, "GetFontsDirectory",  _GetFontsDirectory);
-        NSV8Objects::Template_Set(result, "GetFileString",      _GetFileString);
-        NSV8Objects::Template_Set(result, "GetEditorType",      _GetEditorType);
-        NSV8Objects::Template_Set(result, "CheckNextChange",    _CheckNextChange);
-        NSV8Objects::Template_Set(result, "GetCountChanges",    _GetChangesCount);
-        NSV8Objects::Template_Set(result, "GetChangesFile",     _GetChangesFile);
-        NSV8Objects::Template_Set(result, "Save_AllocNative",   _Save_AllocNative);
-        NSV8Objects::Template_Set(result, "Save_ReAllocNative", _Save_ReAllocNative);
-        NSV8Objects::Template_Set(result, "Save_End",           _Save_End);
-        NSV8Objects::Template_Set(result, "AddImageInChanges",  _AddImageInChanges);
-        NSV8Objects::Template_Set(result, "ConsoleLog",         _ConsoleLog);
-        NSV8Objects::Template_Set(result, "SaveChanges",        _SaveChanges);
-        NSV8Objects::Template_Set(result, "ZipOpen",            _zipOpenFile);
-        NSV8Objects::Template_Set(result, "ZipOpenBase64",      _zipOpenFileBase64);
-        NSV8Objects::Template_Set(result, "ZipFileAsString",    _zipGetFileAsString);
-        NSV8Objects::Template_Set(result, "ZipFileAsBinary",    _zipGetFileAsBinary);
-        NSV8Objects::Template_Set(result, "ZipClose",           _zipCloseFile);
-        NSV8Objects::Template_Set(result, "getImageUrl",        _GetImageUrl);
-        NSV8Objects::Template_Set(result, "getImagesDirectory", _GetImagesPath);
-        NSV8Objects::Template_Set(result, "GetImageOriginalSize", _GetImageOriginalSize);
-
-        return handle_scope.Escape(result);
-    }
-
-    // Без SaveChanges
-    v8::Handle<v8::ObjectTemplate> CreateNativeControlTemplateBuilder(v8::Isolate* isolate)
-    {
-        v8::EscapableHandleScope handle_scope(isolate);
-
-        v8::Local<v8::ObjectTemplate> result = v8::ObjectTemplate::New(V8IsolateOneArg);
-        result->SetInternalFieldCount(1);
-
-        NSV8Objects::Template_Set(result, "SetFilePath",        _SetFilePath);
-        NSV8Objects::Template_Set(result, "GetFilePath",        _GetFilePath);
-        NSV8Objects::Template_Set(result, "SetFileId",          _SetFileId);
-        NSV8Objects::Template_Set(result, "GetFileId",          _GetFileId);
-        NSV8Objects::Template_Set(result, "GetFileBinary",      _GetFileArrayBuffer);
-        NSV8Objects::Template_Set(result, "GetFontBinary",      _GetFontArrayBuffer);
-        NSV8Objects::Template_Set(result, "GetFontsDirectory",  _GetFontsDirectory);
-        NSV8Objects::Template_Set(result, "GetFileString",      _GetFileString);
-        NSV8Objects::Template_Set(result, "GetEditorType",      _GetEditorType);
-        NSV8Objects::Template_Set(result, "CheckNextChange",    _CheckNextChange);
-        NSV8Objects::Template_Set(result, "GetCountChanges",    _GetChangesCount);
-        NSV8Objects::Template_Set(result, "GetChangesFile",     _GetChangesFile);
-        NSV8Objects::Template_Set(result, "Save_AllocNative",   _Save_AllocNative);
-        NSV8Objects::Template_Set(result, "Save_ReAllocNative", _Save_ReAllocNative);
-        NSV8Objects::Template_Set(result, "Save_End",           _Save_End);
-        NSV8Objects::Template_Set(result, "AddImageInChanges",  _AddImageInChanges);
-        NSV8Objects::Template_Set(result, "ConsoleLog",         _ConsoleLog);
-        NSV8Objects::Template_Set(result, "ZipOpen",            _zipOpenFile);
-        NSV8Objects::Template_Set(result, "ZipOpenBase64",      _zipOpenFileBase64);
-        NSV8Objects::Template_Set(result, "ZipFileAsString",    _zipGetFileAsString);
-        NSV8Objects::Template_Set(result, "ZipFileAsBinary",    _zipGetFileAsBinary);
-        NSV8Objects::Template_Set(result, "ZipClose",           _zipCloseFile);
-        NSV8Objects::Template_Set(result, "getImageUrl",        _GetImageUrl);
-        NSV8Objects::Template_Set(result, "getImagesDirectory", _GetImagesPath);
-        NSV8Objects::Template_Set(result, "GetImageOriginalSize", _GetImageOriginalSize);
-
-        return handle_scope.Escape(result);
-    }
-
-    void CreateNativeObject(const v8::FunctionCallbackInfo<v8::Value>& args)
-    {
-        v8::Isolate* isolate = args.GetIsolate();
-        v8::HandleScope scope(isolate);
-
-        v8::Handle<v8::ObjectTemplate> NativeObjectTemplate = CreateNativeControlTemplate(isolate);
-        CNativeControlEmbed* pNativeObject = new CNativeControlEmbed();
-
-        v8::Local<v8::Object> obj = NativeObjectTemplate->NewInstance(isolate->GetCurrentContext()).ToLocalChecked();
-        obj->SetInternalField(0, v8::External::New(CV8Worker::GetCurrent(), pNativeObject));
-
-        args.GetReturnValue().Set(obj);
-    }
-
-    // Без SaveChanges
-    void CreateNativeObjectBuilder(const v8::FunctionCallbackInfo<v8::Value>& args)
-    {
-        v8::Isolate* isolate = args.GetIsolate();
-        v8::HandleScope scope(isolate);
-
-        v8::Handle<v8::ObjectTemplate> NativeObjectTemplate = CreateNativeControlTemplateBuilder(isolate);
-        CNativeControlEmbed* pNativeObject = new CNativeControlEmbed();
-
-        v8::Local<v8::Object> obj = NativeObjectTemplate->NewInstance(isolate->GetCurrentContext()).ToLocalChecked();
-        obj->SetInternalField(0, v8::External::New(CV8Worker::GetCurrent(), pNativeObject));
-
-        args.GetReturnValue().Set(obj);
-    }
+#define CURRENTWRAPPER CNativeControlEmbed
+
+	FUNCTION_WRAPPER_V8(_GetFilePath, GetFilePath)
+	FUNCTION_WRAPPER_V8_1(_SetFilePath, SetFilePath)
+	FUNCTION_WRAPPER_V8(_GetFileId, GetFileId)
+	FUNCTION_WRAPPER_V8_1(_SetFileId, SetFileId)
+	FUNCTION_WRAPPER_V8_1(_GetFileArrayBuffer, GetFileBinary)
+	FUNCTION_WRAPPER_V8_1(_GetFontArrayBuffer, GetFontBinary)
+	FUNCTION_WRAPPER_V8(_GetFontsDirectory, GetFontsDirectory)
+	FUNCTION_WRAPPER_V8_1(_GetFileString, GetFileString)
+	FUNCTION_WRAPPER_V8(_GetEditorType, GetEditorType)
+	FUNCTION_WRAPPER_V8(_CheckNextChange, CheckNextChange)
+	FUNCTION_WRAPPER_V8(_GetChangesCount, GetCountChanges)
+	FUNCTION_WRAPPER_V8_1(_GetChangesFile, GetChangesFile)
+	FUNCTION_WRAPPER_V8_1(_Save_AllocNative, Save_AllocNative)
+	FUNCTION_WRAPPER_V8_2(_Save_ReAllocNative, Save_ReAllocNative)
+	FUNCTION_WRAPPER_V8_2(_Save_End, Save_End)
+	FUNCTION_WRAPPER_V8_1(_AddImageInChanges, AddImageInChanges)
+	FUNCTION_WRAPPER_V8_1(_ConsoleLog, ConsoleLog)
+	FUNCTION_WRAPPER_V8_3(_SaveChanges, SaveChanges)
+	FUNCTION_WRAPPER_V8_1(_zipOpenFile, zipOpenFile)
+	FUNCTION_WRAPPER_V8_1(_zipOpenFileBase64, zipOpenFileBase64)
+	FUNCTION_WRAPPER_V8_1(_zipGetFileAsString, zipGetFileAsString)
+	FUNCTION_WRAPPER_V8_1(_zipGetFileAsBinary, zipGetFileAsBinary)
+	FUNCTION_WRAPPER_V8(_zipCloseFile, zipCloseFile)
+	FUNCTION_WRAPPER_V8_1(_GetImageUrl, GetImageUrl)
+	FUNCTION_WRAPPER_V8_1(_GetImageOriginalSize, GetImageOriginalSize)
+	FUNCTION_WRAPPER_V8(_GetImagesPath, GetImagesPath)
+
+	v8::Handle<v8::ObjectTemplate> CreateNativeControlTemplate(v8::Isolate* isolate)
+	{
+		v8::EscapableHandleScope handle_scope(isolate);
+
+		v8::Local<v8::ObjectTemplate> result = v8::ObjectTemplate::New(V8IsolateOneArg);
+		result->SetInternalFieldCount(1);
+
+		NSV8Objects::Template_Set(result, "SetFilePath",        _SetFilePath);
+		NSV8Objects::Template_Set(result, "GetFilePath",        _GetFilePath);
+		NSV8Objects::Template_Set(result, "SetFileId",          _SetFileId);
+		NSV8Objects::Template_Set(result, "GetFileId",          _GetFileId);
+		NSV8Objects::Template_Set(result, "GetFileBinary",      _GetFileArrayBuffer);
+		NSV8Objects::Template_Set(result, "GetFontBinary",      _GetFontArrayBuffer);
+		NSV8Objects::Template_Set(result, "GetFontsDirectory",  _GetFontsDirectory);
+		NSV8Objects::Template_Set(result, "GetFileString",      _GetFileString);
+		NSV8Objects::Template_Set(result, "GetEditorType",      _GetEditorType);
+		NSV8Objects::Template_Set(result, "CheckNextChange",    _CheckNextChange);
+		NSV8Objects::Template_Set(result, "GetCountChanges",    _GetChangesCount);
+		NSV8Objects::Template_Set(result, "GetChangesFile",     _GetChangesFile);
+		//NSV8Objects::Template_Set(result, "Save_AllocNative",   _Save_AllocNative);
+		//NSV8Objects::Template_Set(result, "Save_ReAllocNative", _Save_ReAllocNative);
+		NSV8Objects::Template_Set(result, "Save_End",           _Save_End);
+		NSV8Objects::Template_Set(result, "AddImageInChanges",  _AddImageInChanges);
+		NSV8Objects::Template_Set(result, "ConsoleLog",         _ConsoleLog);
+		NSV8Objects::Template_Set(result, "SaveChanges",        _SaveChanges);
+		NSV8Objects::Template_Set(result, "ZipOpen",            _zipOpenFile);
+		NSV8Objects::Template_Set(result, "ZipOpenBase64",      _zipOpenFileBase64);
+		NSV8Objects::Template_Set(result, "ZipFileAsString",    _zipGetFileAsString);
+		NSV8Objects::Template_Set(result, "ZipFileAsBinary",    _zipGetFileAsBinary);
+		NSV8Objects::Template_Set(result, "ZipClose",           _zipCloseFile);
+		NSV8Objects::Template_Set(result, "getImageUrl",        _GetImageUrl);
+		NSV8Objects::Template_Set(result, "getImagesDirectory", _GetImagesPath);
+		NSV8Objects::Template_Set(result, "GetImageOriginalSize", _GetImageOriginalSize);
+
+		return handle_scope.Escape(result);
+	}
+
+	// Без SaveChanges
+	v8::Handle<v8::ObjectTemplate> CreateNativeControlTemplateBuilder(v8::Isolate* isolate)
+	{
+		v8::EscapableHandleScope handle_scope(isolate);
+
+		v8::Local<v8::ObjectTemplate> result = v8::ObjectTemplate::New(V8IsolateOneArg);
+		result->SetInternalFieldCount(1);
+
+		NSV8Objects::Template_Set(result, "SetFilePath",        _SetFilePath);
+		NSV8Objects::Template_Set(result, "GetFilePath",        _GetFilePath);
+		NSV8Objects::Template_Set(result, "SetFileId",          _SetFileId);
+		NSV8Objects::Template_Set(result, "GetFileId",          _GetFileId);
+		NSV8Objects::Template_Set(result, "GetFileBinary",      _GetFileArrayBuffer);
+		NSV8Objects::Template_Set(result, "GetFontBinary",      _GetFontArrayBuffer);
+		NSV8Objects::Template_Set(result, "GetFontsDirectory",  _GetFontsDirectory);
+		NSV8Objects::Template_Set(result, "GetFileString",      _GetFileString);
+		NSV8Objects::Template_Set(result, "GetEditorType",      _GetEditorType);
+		NSV8Objects::Template_Set(result, "CheckNextChange",    _CheckNextChange);
+		NSV8Objects::Template_Set(result, "GetCountChanges",    _GetChangesCount);
+		NSV8Objects::Template_Set(result, "GetChangesFile",     _GetChangesFile);
+		//NSV8Objects::Template_Set(result, "Save_AllocNative",   _Save_AllocNative);
+		//NSV8Objects::Template_Set(result, "Save_ReAllocNative", _Save_ReAllocNative);
+		NSV8Objects::Template_Set(result, "Save_End",           _Save_End);
+		NSV8Objects::Template_Set(result, "AddImageInChanges",  _AddImageInChanges);
+		NSV8Objects::Template_Set(result, "ConsoleLog",         _ConsoleLog);
+		NSV8Objects::Template_Set(result, "ZipOpen",            _zipOpenFile);
+		NSV8Objects::Template_Set(result, "ZipOpenBase64",      _zipOpenFileBase64);
+		NSV8Objects::Template_Set(result, "ZipFileAsString",    _zipGetFileAsString);
+		NSV8Objects::Template_Set(result, "ZipFileAsBinary",    _zipGetFileAsBinary);
+		NSV8Objects::Template_Set(result, "ZipClose",           _zipCloseFile);
+		NSV8Objects::Template_Set(result, "getImageUrl",        _GetImageUrl);
+		NSV8Objects::Template_Set(result, "getImagesDirectory", _GetImagesPath);
+		NSV8Objects::Template_Set(result, "GetImageOriginalSize", _GetImageOriginalSize);
+
+		return handle_scope.Escape(result);
+	}
+
+	void CreateNativeObject(const v8::FunctionCallbackInfo<v8::Value>& args)
+	{
+		v8::Isolate* isolate = args.GetIsolate();
+		v8::HandleScope scope(isolate);
+
+		if (CIsolateAdditionalData::CheckSingletonType(isolate, CIsolateAdditionalData::iadtSingletonNative))
+		{
+			args.GetReturnValue().Set(v8::Undefined(isolate));
+			return;
+		}
+
+		v8::Handle<v8::ObjectTemplate> NativeObjectTemplate = CreateNativeControlTemplate(isolate);
+		CNativeControlEmbed* pNativeObject = new CNativeControlEmbed();
+
+		v8::Local<v8::Object> obj = NativeObjectTemplate->NewInstance(isolate->GetCurrentContext()).ToLocalChecked();
+		obj->SetInternalField(0, v8::External::New(CV8Worker::GetCurrent(), pNativeObject));
+
+		args.GetReturnValue().Set(obj);
+	}
+
+	// Без SaveChanges
+	void CreateNativeObjectBuilder(const v8::FunctionCallbackInfo<v8::Value>& args)
+	{
+		v8::Isolate* isolate = args.GetIsolate();
+		v8::HandleScope scope(isolate);
+
+		if (CIsolateAdditionalData::CheckSingletonType(isolate, CIsolateAdditionalData::iadtSingletonNative))
+		{
+			args.GetReturnValue().Set(v8::Undefined(isolate));
+			return;
+		}
+
+		v8::Handle<v8::ObjectTemplate> NativeObjectTemplate = CreateNativeControlTemplateBuilder(isolate);
+		CNativeControlEmbed* pNativeObject = new CNativeControlEmbed();
+
+		v8::Local<v8::Object> obj = NativeObjectTemplate->NewInstance(isolate->GetCurrentContext()).ToLocalChecked();
+		obj->SetInternalField(0, v8::External::New(CV8Worker::GetCurrent(), pNativeObject));
+
+		args.GetReturnValue().Set(obj);
+	}
 }
 
 void CNativeControlEmbed::CreateObjectInContext(const std::string& name, JSSmart<CJSContext> context)
 {
-    v8::Isolate* current = CV8Worker::GetCurrent();
-    context->m_internal->m_global->Set(current, name.c_str(), v8::FunctionTemplate::New(current, NSNativeControl::CreateNativeObject));
+	v8::Isolate* current = CV8Worker::GetCurrent();
+	context->m_internal->m_global->Set(current, name.c_str(), v8::FunctionTemplate::New(current, NSNativeControl::CreateNativeObject));
 }
 
 void CNativeControlEmbed::CreateObjectBuilderInContext(const std::string& name, JSSmart<CJSContext> context)
 {
-    v8::Isolate* current = CV8Worker::GetCurrent();
-    context->m_internal->m_global->Set(current, name.c_str(), v8::FunctionTemplate::New(current, NSNativeControl::CreateNativeObjectBuilder));
+	v8::Isolate* current = CV8Worker::GetCurrent();
+	context->m_internal->m_global->Set(current, name.c_str(), v8::FunctionTemplate::New(current, NSNativeControl::CreateNativeObjectBuilder));
 }

programming_language: C++
filename: v8_base.cpp
change_type: ModificationType.MODIFY
diff: @@ -219,6 +219,13 @@ namespace NSJSBase
 #ifdef V8_INSPECTOR
 		v8_debug::disposeInspector(m_internal->m_context);
 #endif
+		unsigned int nEmbedDataCount = m_internal->m_isolate->GetNumberOfDataSlots();
+		for (unsigned int i = 0; i < nEmbedDataCount; ++i)
+		{
+			CIsolateAdditionalData* pAdditionData = (CIsolateAdditionalData*)m_internal->m_isolate->GetData(i);
+			delete pAdditionData;
+		}
+
 		m_internal->m_isolate->Dispose();
 		m_internal->m_isolate = NULL;
 	}

programming_language: C++
filename: v8_base.h
change_type: ModificationType.MODIFY
diff: @@ -72,6 +72,38 @@ public:
 };
 #endif
 
+class CIsolateAdditionalData
+{
+public:
+	enum IsolateAdditionlDataType {
+		iadtSingletonNative = 0,
+		iadtUndefined = 255
+	};
+
+	IsolateAdditionlDataType m_eType;
+public:
+	CIsolateAdditionalData(const IsolateAdditionlDataType& type = iadtUndefined) { m_eType = type; }
+	virtual ~CIsolateAdditionalData() {}
+
+	static bool CheckSingletonType(v8::Isolate* isolate, const IsolateAdditionlDataType& type, const bool& isAdd = true)
+	{
+		unsigned int nCount = isolate->GetNumberOfDataSlots();
+		for (unsigned int i = 0; i < nCount; ++i)
+		{
+			CIsolateAdditionalData* pData = (CIsolateAdditionalData*)isolate->GetData(i);
+			if (pData->m_eType == type)
+				return true;
+		}
+
+		if (isAdd)
+		{
+			isolate->SetData(nCount, (void*)(new CIsolateAdditionalData(type)));
+		}
+
+		return false;
+	}
+};
+
 class CV8Initializer
 {
 private:

programming_language: C++