1 /*
2  *
3  * Copyright (c) 1998-2004
4  * John Maddock
5  *
6  * Use, modification and distribution are subject to the
7  * Boost Software License, Version 1.0. (See accompanying file
8  * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9  *
10  */
11 
12  /*
13   *   LOCATION:    see http://www.boost.org for most recent version.
14   *   FILE:        regex.cpp
15   *   VERSION:     see <boost/version.hpp>
16   *   DESCRIPTION: Misc boost::regbase member funnctions.
17   */
18 
19 
20 #define BOOST_REGEX_SOURCE
21 
22 #include <boost/regex/config.hpp>
23 
24 #ifdef BOOST_REGEX_HAS_MS_STACK_GUARD
25 
26 #include <malloc.h>
27 
28 #ifndef WIN32_LEAN_AND_MEAN
29 #  define WIN32_LEAN_AND_MEAN
30 #endif
31 #ifndef NOMINMAX
32 #  define NOMINMAX
33 #endif
34 #define NOGDI
35 #define NOUSER
36 #include <windows.h>
37 #include <stdexcept>
38 #include <boost/regex/pattern_except.hpp>
39 #include <boost/regex/v4/protected_call.hpp>
40 
41 namespace boost {
42 namespace BOOST_REGEX_DETAIL_NS {
43 
execute_eror()44 static void execute_eror()
45 {
46    // we only get here after a stack overflow,
47    // this has to be a separate proceedure because we
48    // can't mix __try{}__except block with local objects
49    // that have destructors:
50    reset_stack_guard_page();
51    std::runtime_error err("Out of stack space, while attempting to match a regular expression.");
52    raise_runtime_error(err);
53 }
54 
execute() const55 bool BOOST_REGEX_CALL abstract_protected_call::execute()const
56 {
57    __try{
58       return this->call();
59    }__except(EXCEPTION_STACK_OVERFLOW == GetExceptionCode())
60    {
61       execute_eror();
62    }
63    // We never really get here at all:
64    return false;
65 }
66 
reset_stack_guard_page()67 BOOST_REGEX_DECL void BOOST_REGEX_CALL reset_stack_guard_page()
68 {
69 #if defined(BOOST_REGEX_HAS_MS_STACK_GUARD) && defined(_MSC_VER) && (_MSC_VER >= 1300)
70    _resetstkoflw();
71 #else
72    //
73    // We need to locate the current page being used by the stack,
74    // move to the page below it and then deallocate and protect
75    // that page.  Note that ideally we would protect only the lowest
76    // stack page that has been allocated: in practice there
77    // seems to be no easy way to locate this page, in any case as
78    // long as the next page is protected, then Windows will figure
79    // the rest out for us...
80    //
81    SYSTEM_INFO si;
82    GetSystemInfo(&si);
83    MEMORY_BASIC_INFORMATION mi;
84    DWORD previous_protection_status;
85    //
86    // this is an address in our stack space:
87    //
88    LPBYTE page = (LPBYTE)&page;
89    //
90    // Get the current memory page in use:
91    //
92    VirtualQuery(page, &mi, sizeof(mi));
93    //
94    // Go to the page one below this:
95    //
96    page = (LPBYTE)(mi.BaseAddress)-si.dwPageSize;
97    //
98    // Free and protect everything from the start of the
99    // allocation range, to the end of the page below the
100    // one in use:
101    //
102    if (!VirtualFree(mi.AllocationBase, (LPBYTE)page - (LPBYTE)mi.AllocationBase, MEM_DECOMMIT)
103       || !VirtualProtect(page, si.dwPageSize, PAGE_GUARD | PAGE_READWRITE, &previous_protection_status))
104    {
105       throw std::bad_exception();
106    }
107 #endif
108 }
109 }
110 } // namspaces
111 #endif
112 
113 #if defined(BOOST_RE_USE_VCL) && defined(BOOST_REGEX_DYN_LINK)
114 
DllEntryPoint(HINSTANCE,unsigned long,void *)115 int WINAPI DllEntryPoint(HINSTANCE , unsigned long , void*)
116 {
117    return 1;
118 }
119 #endif
120 
121