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/config.hpp>
23 #include <new>
24 #include <boost/regex.hpp>
25 #include <boost/throw_exception.hpp>
26 
27 #if defined(BOOST_REGEX_HAS_MS_STACK_GUARD) && defined(_MSC_VER) && (_MSC_VER >= 1300)
28 #  include <malloc.h>
29 #endif
30 #ifdef BOOST_REGEX_HAS_MS_STACK_GUARD
31 #ifndef WIN32_LEAN_AND_MEAN
32 #  define WIN32_LEAN_AND_MEAN
33 #endif
34 #ifndef NOMINMAX
35 #  define NOMINMAX
36 #endif
37 #define NOGDI
38 #define NOUSER
39 #include <windows.h>
40 #endif
41 
42 #if defined(BOOST_REGEX_NON_RECURSIVE) && !defined(BOOST_REGEX_V3)
43 #if BOOST_REGEX_MAX_CACHE_BLOCKS == 0
44 #include <new>
45 #else
46 #include <boost/regex/v4/mem_block_cache.hpp>
47 #endif
48 #endif
49 
50 #ifdef BOOST_INTEL
51 #pragma warning(disable:383)
52 #endif
53 
54 namespace boost{
55 
56 //
57 // fix: these are declared out of line here to ensure
58 // that dll builds contain the Virtual table for these
59 // types - this ensures that exceptions can be thrown
60 // from the dll and caught in an exe.
regex_error(const std::string & s,regex_constants::error_type err,std::ptrdiff_t pos)61 regex_error::regex_error(const std::string& s, regex_constants::error_type err, std::ptrdiff_t pos)
62    : std::runtime_error(s)
63    , m_error_code(err)
64    , m_position(pos)
65 {
66 }
67 
regex_error(regex_constants::error_type err)68 regex_error::regex_error(regex_constants::error_type err)
69    : std::runtime_error(::boost::BOOST_REGEX_DETAIL_NS::get_default_error_string(err))
70    , m_error_code(err)
71    , m_position(0)
72 {
73 }
74 
~regex_error()75 regex_error::~regex_error() throw()
76 {
77 }
78 
raise() const79 void regex_error::raise()const
80 {
81 #ifndef BOOST_NO_EXCEPTIONS
82    ::boost::throw_exception(*this);
83 #endif
84 }
85 
86 
87 
88 namespace BOOST_REGEX_DETAIL_NS{
89 
raise_runtime_error(const std::runtime_error & ex)90 BOOST_REGEX_DECL void BOOST_REGEX_CALL raise_runtime_error(const std::runtime_error& ex)
91 {
92    ::boost::throw_exception(ex);
93 }
94 //
95 // error checking API:
96 //
verify_options(boost::regex::flag_type,match_flag_type mf)97 BOOST_REGEX_DECL void BOOST_REGEX_CALL verify_options(boost::regex::flag_type /*ef*/, match_flag_type mf)
98 {
99 #ifndef BOOST_REGEX_V3
100    //
101    // can't mix match_extra with POSIX matching rules:
102    //
103    if((mf & match_extra) && (mf & match_posix))
104    {
105       std::logic_error msg("Usage Error: Can't mix regular expression captures with POSIX matching rules");
106       throw_exception(msg);
107    }
108 #endif
109 }
110 
111 #ifdef BOOST_REGEX_HAS_MS_STACK_GUARD
112 
execute_eror()113 static void execute_eror()
114 {
115    // we only get here after a stack overflow,
116    // this has to be a separate proceedure because we
117    // can't mix __try{}__except block with local objects
118    // that have destructors:
119    reset_stack_guard_page();
120    std::runtime_error err("Out of stack space, while attempting to match a regular expression.");
121    raise_runtime_error(err);
122 }
123 
execute() const124 bool BOOST_REGEX_CALL abstract_protected_call::execute()const
125 {
126    __try{
127       return this->call();
128    }__except(EXCEPTION_STACK_OVERFLOW == GetExceptionCode())
129    {
130       execute_eror();
131    }
132    // We never really get here at all:
133    return false;
134 }
135 
reset_stack_guard_page()136 BOOST_REGEX_DECL void BOOST_REGEX_CALL reset_stack_guard_page()
137 {
138 #if defined(BOOST_REGEX_HAS_MS_STACK_GUARD) && defined(_MSC_VER) && (_MSC_VER >= 1300)
139    _resetstkoflw();
140 #else
141    //
142    // We need to locate the current page being used by the stack,
143    // move to the page below it and then deallocate and protect
144    // that page.  Note that ideally we would protect only the lowest
145    // stack page that has been allocated: in practice there
146    // seems to be no easy way to locate this page, in any case as
147    // long as the next page is protected, then Windows will figure
148    // the rest out for us...
149    //
150    SYSTEM_INFO si;
151    GetSystemInfo(&si);
152    MEMORY_BASIC_INFORMATION mi;
153    DWORD previous_protection_status;
154    //
155    // this is an address in our stack space:
156    //
157    LPBYTE page = (LPBYTE)&page;
158    //
159    // Get the current memory page in use:
160    //
161    VirtualQuery(page, &mi, sizeof(mi));
162    //
163    // Go to the page one below this:
164    //
165    page = (LPBYTE)(mi.BaseAddress)-si.dwPageSize;
166    //
167    // Free and protect everything from the start of the
168    // allocation range, to the end of the page below the
169    // one in use:
170    //
171    if (!VirtualFree(mi.AllocationBase, (LPBYTE)page - (LPBYTE)mi.AllocationBase, MEM_DECOMMIT)
172       || !VirtualProtect(page, si.dwPageSize, PAGE_GUARD | PAGE_READWRITE, &previous_protection_status))
173    {
174       throw std::bad_exception();
175    }
176 #endif
177 }
178 #endif
179 
180 #if defined(BOOST_REGEX_NON_RECURSIVE) && !defined(BOOST_REGEX_V3)
181 
182 #if BOOST_REGEX_MAX_CACHE_BLOCKS == 0
183 
get_mem_block()184 BOOST_REGEX_DECL void* BOOST_REGEX_CALL get_mem_block()
185 {
186    return ::operator new(BOOST_REGEX_BLOCKSIZE);
187 }
188 
put_mem_block(void * p)189 BOOST_REGEX_DECL void BOOST_REGEX_CALL put_mem_block(void* p)
190 {
191    ::operator delete(p);
192 }
193 
194 #else
195 
196 #if defined(BOOST_REGEX_MEM_BLOCK_CACHE_LOCK_FREE)
197 mem_block_cache block_cache = { { {nullptr} } } ;
198 #elif defined(BOOST_HAS_THREADS)
199 mem_block_cache block_cache = { 0, 0, BOOST_STATIC_MUTEX_INIT, };
200 #else
201 mem_block_cache block_cache = { 0, 0, };
202 #endif
203 
get_mem_block()204 BOOST_REGEX_DECL void* BOOST_REGEX_CALL get_mem_block()
205 {
206    return block_cache.get();
207 }
208 
put_mem_block(void * p)209 BOOST_REGEX_DECL void BOOST_REGEX_CALL put_mem_block(void* p)
210 {
211    block_cache.put(p);
212 }
213 
214 #endif
215 
216 #endif
217 
218 } // namespace BOOST_REGEX_DETAIL_NS
219 
220 
221 
222 } // namespace boost
223 
224 #if defined(BOOST_RE_USE_VCL) && defined(BOOST_REGEX_DYN_LINK)
225 
DllEntryPoint(HINSTANCE,unsigned long,void *)226 int WINAPI DllEntryPoint(HINSTANCE , unsigned long , void*)
227 {
228    return 1;
229 }
230 #endif
231 
232