diff options
author | Marcelo Lira <marcelo.lira@openbossa.org> | 2011-05-31 12:26:19 -0300 |
---|---|---|
committer | Hugo Parente Lima <hugo.pl@gmail.com> | 2012-03-08 16:15:26 -0300 |
commit | e71fba71859985a5fe9b81c016451ac090cfc145 (patch) | |
tree | 0429d70d9e8a4bca21fa64f09c478fc11f659770 /generator | |
parent | 7b731d702c64d172e192aa1876e4a6fade6c38d7 (diff) |
Fixed injected code processing to avoid infinite recursion in virtual method calls.
Unit tests were also added.
Diffstat (limited to 'generator')
-rw-r--r-- | generator/shibokengenerator.cpp | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/generator/shibokengenerator.cpp b/generator/shibokengenerator.cpp index 6e300d564..ec9a4a8ad 100644 --- a/generator/shibokengenerator.cpp +++ b/generator/shibokengenerator.cpp @@ -1102,6 +1102,34 @@ ShibokenGenerator::ExtendedConverterData ShibokenGenerator::getExtendedConverter return extConvs; } +static QString getArgumentsFromMethodCall(const QString& str) +{ + // It would be way nicer to be able to use a Perl like + // regular expression that accepts temporary variables + // to count the parenthesis. + // For more information check this: + // http://perl.plover.com/yak/regex/samples/slide083.html + static QString funcCall("%CPPSELF.%FUNCTION_NAME"); + int pos = str.indexOf(funcCall); + if (pos == -1) + return QString(); + pos = pos + funcCall.count(); + while (str.at(pos) == ' ' || str.at(pos) == '\t') + ++pos; + if (str.at(pos) == '(') + ++pos; + int begin = pos; + int counter = 1; + while (counter != 0) { + if (str.at(pos) == '(') + ++counter; + else if (str.at(pos) == ')') + --counter; + ++pos; + } + return str.mid(begin, pos-begin-1); +} + void ShibokenGenerator::writeCodeSnips(QTextStream& s, const CodeSnipList& codeSnips, CodeSnip::Position position, @@ -1220,6 +1248,16 @@ void ShibokenGenerator::writeCodeSnips(QTextStream& s, if (func->isComparisonOperator()) replacement = "%1."; + if (func->isVirtual() && !func->isAbstract() && (!avoidProtectedHack() || !func->isProtected())) { + QString methodCallArgs = getArgumentsFromMethodCall(code); + if (!methodCallArgs.isNull()) { + code.replace(QString("%CPPSELF.%FUNCTION_NAME(%1)").arg(methodCallArgs), + QString("(Shiboken::Object::hasCppWrapper(reinterpret_cast<SbkObject*>(%1))" + " ? %CPPSELF->::%TYPE::%FUNCTION_NAME(%2)" + " : %CPPSELF.%FUNCTION_NAME(%2))").arg(pySelf).arg(methodCallArgs)); + } + } + code.replace("%CPPSELF.", replacement.arg(cppSelf)); code.replace("%CPPSELF", cppSelf); |