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