2012-10-01 5 views
5

HtmlAgilityPack을 사용하여 약 200,000 개의 HTML 문서를 구문 분석하고 있습니다.해결 방법 StackOverflowException

이러한 문서의 내용을 예측할 수는 없지만 이러한 문서 중 하나는 StackOverflowException으로 인해 내 응용 프로그램이 실패하게됩니다. 문서는이 HTML이 포함

<ol> 
    <li><li><li><li><li><li>... 
</ol> 

처럼 중첩 된 약 10,000 <li> 요소가 있습니다. HtmlAgilityPack이 HTML을 구문 분석하는 방식으로 인해 StackOverflowException이 발생합니다.

불행히도 StackOverflowException은 .NET 2.0 이상에서는 catch 할 수 없습니다.

스레드 스택의 크기를 더 크게 설정하는 것에 대해 궁금해했으나 스택 크기를 더 크게 설정하면 해킹이 발생합니다. 내 프로그램이 더 많은 메모리를 사용하게됩니다 (내 프로그램은 HTML 처리를 위해 약 50 개의 스레드를 시작하므로 이 모든 쓰레드는 스택 크기가 증가 할 것입니다.) 비슷한 상황을 다시 한번 경험할 수 있다면 수동으로 조정할 필요가 있습니다.

내가 사용할 수있는 다른 해결 방법이 있습니까?

+0

하지 않습니다.다른 라이브러리로 전환한다고 생각하지 않는 한, 스택 크기를 늘리는 것보다 나은 방법은 없습니다. 아마도 스레드를 필요로하는 스레드에 대해서만 스택 크기를 설정하는 방법이 있을까요? –

답변

2

이상적인 장기적인 해결책은 HtmlAgilityPack을 패치하여 호출 스택 대신 힙 스택을 사용하는 것이지만 너무 큰 사업 일 것입니다. 일시적으로 CodePlex 계정 세부 정보를 잃어 버렸지 만, 문제가 발생하면 문제 보고서를 제출할 것입니다. 또한이 문제는 HtmlAgilityPack을 사용하여 사용자가 제출 한 HTML을 위생적으로 처리하는 사이트에 서비스 거부 공격 (DoS) 공격 취약점을 나타낼 수 있습니다. 너무 많이 중첩 된 HTML 문서로 인해 w3wp.exe 프로세스가 중지 될 수 있습니다.

그동안 나는 최대 스레드 스택 크기를 수동으로 무시하는 것이 최선의 방법이라고 생각했습니다. 이전의 성명서에서 스택 크기가 크다는 것은 모든 스레드가 자동으로 메모리를 소비한다는 것을 의미합니다 (메모리 페이지가 늘어날 때마다 스레드 스택에 할당되는 것처럼 보입니다).

<ol><li> 페이지 사본을 만들어 실험을 진행했습니다. 스택 크기가 2^21 바이트 미만이지만 최대 크기가 2^22 일 때 내 프로그램이 실패한 것으로 나타났습니다. 이는 4MB이고 내 책에서 "허용 가능한"해킹으로 전달됩니다.

5

방금 ​​설명한 내용과 동일한 오류가 발생했습니다. 는 HAP 프로젝트 사이트에 패치 ...

http://www.codeplex.com/site/users/view/sjdirect

(2012년 3월 8일에 패치 참조) 또는 문제에 더 설명서를 참조하십시오 여기에 결과를 .... 업로드

https://code.google.com/p/abot/issues/detail?id=77

실제 수정했다 ... 중첩 된 태그의 톤에 의해 발생하는 StackOverflowExceptions을 방지하기 위해 설정 될 수 추가 HtmlDocument.OptionMaxNestedChildNodes합니다. "Document가 X 개 이상의 중첩 된 태그를 가지고 있는데, 이는 태그를 제대로 닫지 않은 페이지 때문일 가능성이 큽니다."라는 메시지와 함께 ApplicationException을 던집니다. 나는 패치 후에 우연를 사용하고 어떻게

... 정말

HtmlDocument hapDoc = new HtmlDocument(); 
hapDoc.OptionMaxNestedChildNodes = 5000;//This is what was added 
string rawContent = GETTHECONTENTHERE 
try 
{ 
    hapDoc.LoadHtml(RawContent);  
} 
catch (Exception e) 
{ 
    //Instead of a stackoverflow exception you should end up here now 
    hapDoc.LoadHtml(""); 
    _logger.Error(e); 
} 
관련 문제