Skip to content

Commit 39cce14

Browse files
committed
Fixed problem with duplicate named groups in regular expressions
1 parent b9e52a1 commit 39cce14

File tree

3 files changed

+75
-17
lines changed

3 files changed

+75
-17
lines changed

regexp.cpp

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
#include "MUSHclient.h"
55
#include "doc.h"
66
#include "dialogs\RegexpProblemDlg.h"
7+
#include "pcre\config.h"
8+
#include "pcre\pcre.h"
9+
#include "pcre\pcre_internal.h"
710

811
#ifdef _DEBUG
912
#define new DEBUG_NEW
@@ -146,4 +149,70 @@ pcre * program;
146149
dlg.m_iColumn = erroroffset + 1;
147150
dlg.DoModal ();
148151
return false; // bad
149-
}
152+
}
153+
154+
155+
// returns a named wildcard
156+
string t_regexp::GetWildcard (const string& sName) const
157+
{
158+
int iNumber = PCRE_ERROR_NOSUBSTRING;
159+
if (IsStringNumber (sName))
160+
iNumber = atoi (sName.c_str ());
161+
else
162+
{
163+
if (m_program == NULL)
164+
iNumber = PCRE_ERROR_NOSUBSTRING;
165+
else
166+
{
167+
/* now do named subpatterns */
168+
int namecount;
169+
pcre_fullinfo(m_program, m_extra, PCRE_INFO_NAMECOUNT, &namecount);
170+
171+
172+
if (namecount > 0)
173+
{
174+
unsigned char *name_table;
175+
int name_entry_size;
176+
unsigned char *tabptr;
177+
int ncapt;
178+
int jchanged;
179+
pcre_fullinfo(m_program, m_extra, PCRE_INFO_CAPTURECOUNT, &ncapt);
180+
pcre_fullinfo(m_program, m_extra, PCRE_INFO_NAMETABLE, &name_table);
181+
pcre_fullinfo(m_program, m_extra, PCRE_INFO_NAMEENTRYSIZE, &name_entry_size);
182+
pcre_fullinfo(m_program, m_extra, PCRE_INFO_JCHANGED, &jchanged);
183+
tabptr = name_table;
184+
set<string> found_strings;
185+
for (int i = 0; i < namecount; i++, tabptr += name_entry_size)
186+
{
187+
int n = (tabptr[0] << 8) | tabptr[1];
188+
const unsigned char * name = tabptr + 2;
189+
// if duplicates were possible then ...
190+
if (jchanged)
191+
{
192+
// this code is to ensure that we don't find a match (eg. mob = Kobold)
193+
// and then if duplicates were allowed, replace Kobold with false.
194+
195+
string sName = (LPCTSTR) name;
196+
197+
// for duplicate names, see if we already added this name
198+
if (found_strings.find (sName) != found_strings.end ())
199+
{
200+
// do not replace if this one is out of range or empty
201+
if (n < 0 || n > m_iCount || GetWildcard (n) == "")
202+
continue;
203+
} // end of duplicate
204+
else
205+
found_strings.insert (sName);
206+
}
207+
208+
if (n >= 0 && n <= m_iCount)
209+
iNumber = n;
210+
211+
} // end of wildcard loop
212+
} // end of having named wildcards
213+
214+
} // end of program not NULL
215+
216+
} // end of wanting a named wildcard
217+
return GetWildcard (iNumber);
218+
} // end of t_regexp::GetWildcard

regexp.h

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -74,20 +74,7 @@ class t_regexp
7474
};
7575

7676
// returns a named wildcard
77-
string GetWildcard (const string& sName) const
78-
{
79-
int iNumber;
80-
if (IsStringNumber (sName))
81-
iNumber = atoi (sName.c_str ());
82-
else
83-
{
84-
if (m_program == NULL)
85-
iNumber = PCRE_ERROR_NOSUBSTRING;
86-
else
87-
iNumber = njg_get_first_set (m_program, sName.c_str (), &m_vOffsets [0]);
88-
}
89-
return GetWildcard (iNumber);
90-
}
77+
string GetWildcard (const string& sName) const;
9178

9279
};
9380

scripting/lua_scripting.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -546,16 +546,18 @@ bool CScriptEngine::ExecuteLua (DISPID & dispid, // dispatch ID, will be set to
546546
pcre_fullinfo(regexp->m_program, regexp->m_extra, PCRE_INFO_NAMECOUNT, &namecount);
547547
if (namecount > 0)
548548
{
549+
int jchanged;
549550
pcre_fullinfo(regexp->m_program, regexp->m_extra, PCRE_INFO_NAMETABLE, &name_table);
550551
pcre_fullinfo(regexp->m_program, regexp->m_extra, PCRE_INFO_NAMEENTRYSIZE, &name_entry_size);
552+
pcre_fullinfo(regexp->m_program, regexp->m_extra, PCRE_INFO_JCHANGED, &jchanged);
551553
tabptr = name_table;
552554
set<string> found_strings;
553555
for (i = 0; i < namecount; i++, tabptr += name_entry_size)
554556
{
555557
int n = (tabptr[0] << 8) | tabptr[1];
556558
const unsigned char * name = tabptr + 2;
557559
// if duplicates were possible then ...
558-
if ((regexp->m_program->options & (PCRE_DUPNAMES | PCRE_JCHANGED)) != 0)
560+
if (jchanged)
559561
{
560562
// this code is to ensure that we don't find a match (eg. mob = Kobold)
561563
// and then if duplicates were allowed, replace Kobold with false.
@@ -566,7 +568,7 @@ bool CScriptEngine::ExecuteLua (DISPID & dispid, // dispatch ID, will be set to
566568
if (found_strings.find (sName) != found_strings.end ())
567569
{
568570
// do not replace if this one is out of range
569-
if (n < 0 || n > ncapt)
571+
if (n < 0 || n > ncapt || regexp->GetWildcard (n) == "")
570572
continue;
571573
} // end of duplicate
572574
else

0 commit comments

Comments
 (0)