Переключение на Главную Страницу Страницы: 1 ОтправитьПечать
Горячая тема (более 10 ответов) Убить 1С при помощи OLE DB (рецепт) (число прочтений - 6556 )
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Убить 1С при помощи OLE DB (рецепт)
09. Ноября 2007 :: 07:33
Печать  
Вот "сколько раз твердили миру", что использовать функции на основе alloca опасно! Улыбка А в OLE DB 1С++ это есть. Что и может привести к печальным последствиям. Вот код:

Код
Выбрать все
Процедура ПриОткрытии ()
	ЗагрузитьВнешнююКомпоненту ("1cpp.dll");
КонецПроцедуры

//-----------------------------------------------------------------------------

Процедура Сформировать ()
	Соединение = СоздатьОбъект ("OLEDBData");
	СтрокаПодключения = Шаблон ("Provider=VFPOLEDB.1; Mode=ReadWrite;
	|Data Source=[КаталогИБ ()];");

	Соединение.Соединение (СтрокаПодключения);

	Команда = Соединение.СоздатьКоманду ();

	КолвоКолонок = 100;

	ИмяКолонки = "1234567890";
	Для Ч = 1 По 10 Цикл
		ИмяКолонки = ИмяКолонки + ИмяКолонки;
	КонецЦикла;
	//Предупреждение (ИмяКолонки);
	ИмяКолонки = "К" + ИмяКолонки;

	ТекстЗапроса = "
	|SELECT TOP 1
	|	ID
	|";

	Для Ч = 1 По КолвоКолонок Цикл
		ТекстЗапроса = ТекстЗапроса + "
		|	,Ном" + Ч + " AS " + ИмяКолонки + "_" + Ч;
	КонецЦикла;

	ТекстЗапроса = ТекстЗапроса + "
	|FROM
	|	$Справочник.Номенклатура
	|";

	Для Ч = 1 По КолвоКолонок Цикл
		ТекстЗапроса = ТекстЗапроса + "
		|	LEFT JOIN $Справочник.Номенклатура AS Ном" + Ч + "
		|";
	КонецЦикла;

	ТекстЗапроса = ТекстЗапроса + "
	|ORDER BY ID
	|";

	ТЗ = Команда.ВыполнитьИнструкцию (ТекстЗапроса);
	ТЗ.ВыбратьСтроку ();
КонецПроцедуры
 



Крашит 1С по "Stack Overflow". Все дело в этом коде:

Код
Выбрать все
	for(ULONG nCol = 0; nCol < nCols; nCol++)
	{
		// заполняем мою структуру
		//
		CString strName = OLE2T(pColumnsInfo[nCol].pwszName); // ЖОПА ЗДЕСЬ

		pColInfo1C[nCol].m_Index	 = nCol;
		pColInfo1C[nCol].m_strName	 = strName;
		pColInfo1C[nCol].m_wType	 = pColumnsInfo[nCol].wType;
		pColInfo1C[nCol].m_nType1C	 = GetType1C(&pColInfo1C[nCol]);
 

  
Наверх
 
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Убить 1С при помощи OLE DB (рецепт)
Ответ #1 - 09. Ноября 2007 :: 07:51
Печать  
Подумал, зачем делать множественные LEFT JOIN? Можно гораздо проще и нагляднее:
Код
Выбрать все
Процедура ПриОткрытии ()
	ЗагрузитьВнешнююКомпоненту ("1cpp.dll");
КонецПроцедуры

//-----------------------------------------------------------------------------

Процедура Сформировать ()
	Соединение = СоздатьОбъект ("OLEDBData");
	СтрокаПодключения = Шаблон ("Provider=VFPOLEDB.1; Mode=ReadWrite;
	|Data Source=[КаталогИБ ()];");

	Соединение.Соединение (СтрокаПодключения);

	Команда = Соединение.СоздатьКоманду ();

	КолвоКолонок = 100;

	ИмяКолонки = "1234567890";
	Для Ч = 1 По 10 Цикл
		ИмяКолонки = ИмяКолонки + ИмяКолонки;
	КонецЦикла;
	//Предупреждение (ИмяКолонки);
	ИмяКолонки = "К" + ИмяКолонки;

	ТекстЗапроса = "
	|SELECT TOP 1
	|	ID
	|";

	Для Ч = 1 По КолвоКолонок Цикл
		ТекстЗапроса = ТекстЗапроса + "
		|	,ID AS " + ИмяКолонки + "_" + Ч;
	КонецЦикла;

	ТекстЗапроса = ТекстЗапроса + "
	|FROM
	|	$Справочник.Номенклатура
	|";

	ТекстЗапроса = ТекстЗапроса + "
	|ORDER BY ID
	|";

	ТЗ = Команда.ВыполнитьИнструкцию (ТекстЗапроса);
	ТЗ.ВыбратьСтроку ();
КонецПроцедуры

 

  
Наверх
 
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Убить 1С при помощи OLE DB (рецепт)
Ответ #2 - 09. Ноября 2007 :: 09:16
Печать  
Олег, в багзиллу, пожалуйста Улыбка
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer &amp;&amp; tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
spock
1c++ developer
1c++ moderator
Отсутствует



Сообщений: 822
Местоположение: Новосибирск
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Убить 1С при помощи OLE DB (рецепт)
Ответ #3 - 09. Ноября 2007 :: 09:22
Печать  
Есть такая потенциальная проблема.
С одной стороны 100 колонок с именами полей в 10241 символ кадлое поле - это сильно.
С другой стороны переполнение стека случилось не там, где обозначена ЖОПА, а гораздо раньше.
Код
Выбрать все
hr = m_pICommandText->SetCommandText(DBGUID_DEFAULT, T2OLE(strSQL)); // другая ЖОПА, но ЖОПА того же рода
 

  
Наверх
ICQ  
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Убить 1С при помощи OLE DB (рецепт)
Ответ #4 - 09. Ноября 2007 :: 09:29
Печать  
artbear писал(а) 09. Ноября 2007 :: 09:16:
Олег, в багзиллу, пожалуйста Улыбка

Данунах. Это не баг - это фича. Вот захочется мне уронить 1С - а тут на тебе: OLE DB под рукой. Удобно же!

PS. http://www.1cpp.ru/bugs/show_bug.cgi?id=3376
  
Наверх
 
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Убить 1С при помощи OLE DB (рецепт)
Ответ #5 - 09. Ноября 2007 :: 09:31
Печать  
spock писал(а) 09. Ноября 2007 :: 09:22:
Есть такая потенциальная проблема.
С одной стороны 100 колонок с именами полей в 10241 символ кадлое поле - это сильно.
С другой стороны переполнение стека случилось не там, где обозначена ЖОПА, а гораздо раньше.
Код
Выбрать все
hr = m_pICommandText->SetCommandText(DBGUID_DEFAULT, T2OLE(strSQL)); // другая ЖОПА, но ЖОПА того же рода
 


Угу, вот начнет кто-нибудь баловаться с автогенерацией запросов, гуиды там юзать в качестве имен колонок или левую инфу в именах кодировать... И тут весь потенциал проявится во всей красе.  Подмигивание
  
Наверх
 
IP записан
 
spock
1c++ developer
1c++ moderator
Отсутствует



Сообщений: 822
Местоположение: Новосибирск
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Убить 1С при помощи OLE DB (рецепт)
Ответ #6 - 09. Ноября 2007 :: 09:36
Печать  
+ А может размер стека для проекта увеличить, а то мне юмор Олега не понятен Улыбка
Да и еще найдутся шутники.
  
Наверх
ICQ  
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Убить 1С при помощи OLE DB (рецепт)
Ответ #7 - 09. Ноября 2007 :: 09:38
Печать  
spock писал(а) 09. Ноября 2007 :: 09:36:
+ А может размер стека для проекта увеличить, а то мне юмор Олега не понятен Улыбка
Да и еще найдутся шутники.

Как ты его увеличишь? 1С++ юзает стек от одинэса, разве не так? Все равно это полумера.
  
Наверх
 
IP записан
 
spock
1c++ developer
1c++ moderator
Отсутствует



Сообщений: 822
Местоположение: Новосибирск
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Убить 1С при помощи OLE DB (рецепт)
Ответ #8 - 09. Ноября 2007 :: 09:55
Печать  
  
Наверх
ICQ  
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Убить 1С при помощи OLE DB (рецепт)
Ответ #9 - 09. Ноября 2007 :: 10:00
Печать  
spock писал(а) 09. Ноября 2007 :: 09:55:

ИМХО, не туда тебя понесло. Впрочем, дело твое.
  
Наверх
 
IP записан
 
spock
1c++ developer
1c++ moderator
Отсутствует



Сообщений: 822
Местоположение: Новосибирск
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Убить 1С при помощи OLE DB (рецепт)
Ответ #10 - 09. Ноября 2007 :: 10:10
Печать  
епт, вот оно че, Михалыч...
Изначально я не догнал при чем здесь alloca + не догнал почему стек слетает.
Агуеть, а на кой спрашивается оно так реализовано:
Цитата:
Allocates memory on the stack.
...
alloca
...

День прожит не зря.
  
Наверх
ICQ  
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Убить 1С при помощи OLE DB (рецепт)
Ответ #11 - 09. Ноября 2007 :: 10:10
Печать  
Соответствующий юнит-тест занесен в базу тестирования 1С++.
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer &amp;&amp; tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Убить 1С при помощи OLE DB (рецепт)
Ответ #12 - 09. Ноября 2007 :: 10:14
Печать  
Даже не знал про подобную функцию Улыбка
Т.е. лечится просто - использовать не alloca, а обычный new или malloc (что хуже) ?
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer &amp;&amp; tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
Uzhast
1c++ power user
Отсутствует



Сообщений: 1341
Зарегистрирован: 30. Августа 2006
Пол: Мужской
Re: Убить 1С при помощи OLE DB (рецепт)
Ответ #13 - 09. Ноября 2007 :: 10:24
Печать  
artbear писал(а) 09. Ноября 2007 :: 10:14:
Даже не знал про подобную функцию Улыбка
Т.е. лечится просто - использовать не alloca, а обычный new или malloc (что хуже) ?

Лучше не использовать ни то, ни другое. Для этого есть вектор Улыбка
  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: 1
ОтправитьПечать