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

Memory Exhaustion vulnerability in ONLYOFFICE Document Server 4.0.3 through 7.3.2 allows remote attackers to cause a denial of service via crafted JavaScript file.

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

Weakness information:
cwe_id: CWE-835
cwe_name: Loop with Unreachable Exit Condition ('Infinite Loop')
description: The product contains an iteration or loop with an exit condition that cannot be reached, i.e., an infinite loop.
extended_description: If the loop can be influenced by an attacker, this weakness could allow attackers to consume excessive resources such as CPU or memory.
         

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++