aboutsummaryrefslogtreecommitdiffstats
path: root/generator
diff options
context:
space:
mode:
authorMarcelo Lira <marcelo.lira@openbossa.org>2011-05-31 12:26:19 -0300
committerHugo Parente Lima <hugo.pl@gmail.com>2012-03-08 16:15:26 -0300
commite71fba71859985a5fe9b81c016451ac090cfc145 (patch)
tree0429d70d9e8a4bca21fa64f09c478fc11f659770 /generator
parent7b731d702c64d172e192aa1876e4a6fade6c38d7 (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.cpp38
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);