eval()'d code

Gesperrt
Marco76
Beiträge: 11
Registriert: Do 5. Feb 2009, 10:43
Kontaktdaten:

eval()'d code

Beitrag von Marco76 » Di 3. Nov 2009, 18:37

Hi Leute,

ich habe nach einer Migration folgende Fehlermeldung im Frontend

Parse error: syntax error, unexpected ';' in /www/htdocs/w00bebfa/cms/front_content.php(932) : eval()'d code on line 289

Im Backend im Editor

Parse error: syntax error, unexpected ';' in /www/htdocs/w00bebfa/contenido/includes/include.con_editcontent.php(628) : eval()'d code on line 449

Ich habe eine Migration schon so oft gemacht, allerdings bringt mich das gerade in den Wahnsinn!

Hat jemand einen Tipp?

Lieben Dank,
Marco

kummer
Beiträge: 2423
Registriert: Do 6. Mai 2004, 09:17
Wohnort: Bern, Schweiz
Kontaktdaten:

Re: eval()'d code

Beitrag von kummer » Di 3. Nov 2009, 20:10

der fehler müsste in einem modul liegen. wenn du dir im backend die module anschaues (eines nach dem anderen), dann solltest du bei mindestens einem modul eine rote ampel vorfinden. dort müsste dann auch der fehler sein.

zielgerichteter kommst du allerdings ans ziel, wenn du dir den con_code-eintrag anschaust. mit phpmyadmin recherchieren und dann auf zeile 289 schauen. dann siehst du auch gleich, in welchem modul der fehler auftritt.
aitsu.org :: schnell - flexibel - komfortabel :: Version 2.2.0 (since June 22, 2011) (jetzt mit dual license GPL/kommerziell)

Horst Wiese
Beiträge: 28
Registriert: Do 28. Mai 2009, 06:55
Wohnort: Bremen

Re: eval()'d code

Beitrag von Horst Wiese » Fr 30. Apr 2010, 10:39

Hallo Kummer,

nach zwei drei Versuchen habe ich in der con_code-Tabelle das Modul lokalisieren können.
Es ist ein vom ursprünglichen Programmierer selbst geschriebenes, sehr kurzes Modul:

Code: Alles auswählen

<?php
#Includes
cInclude('classes', 'class.template.php');
if ( !is_object($tpl) ) {
    $tpl = new Template;
}
$tpl->reset();
$html2 = "CMS_HTML[2]";
if ($html2 != ""){

    $template = 'detailseite_linkliste.html';
    $tpl->set('s', 'LINKLISTE', "CMS_HTML[2]");

    $tpl->generate('templates/'.$template);
}
?>

Kann es sein, dass dieser Code, der für v.4.6.15 geschrieben wurde, nun in v.4.8.12 nicht mehr funktioniert.
Die Fehlermeldungen variieren, kreisen aber immer um:
Parse error: syntax error, unexpected '[ "<", ";" oder "T_String"]' [...] include.con_editcontent.php(638) : eval()'d code on line [xyz],
sobald ich im Editor was ändere und auf Speichern gehe.

Vielen Dank,
Horst

Oldperl
Beiträge: 4251
Registriert: Do 30. Jun 2005, 22:56
Wohnort: Eltmann, Unterfranken, Bayern
Kontaktdaten:

Re: eval()'d code

Beitrag von Oldperl » Fr 30. Apr 2010, 12:18

Hallo Horst,

könnte es sein das in der "CMS_HTML[2]" Variablen irgendetwas drin steht was nicht funktioniert?
Eventuell diese erst mal Leeren und dann nochmal testen.

Gruß aus Franken

Ortwin
ConLite 2.1, alternatives und stabiles Update von Contenido 4.8.x unter PHP 7.x - Download und Repo auf Gitport.de
phpBO Search Advanced - das Suchwort-Plugin für CONTENIDO 4.9
Mein Entwickler-Blog

Horst Wiese
Beiträge: 28
Registriert: Do 28. Mai 2009, 06:55
Wohnort: Bremen

Re: eval()'d code

Beitrag von Horst Wiese » Fr 30. Apr 2010, 14:34

Hallo Ortwin,

wie mach ich das, diese Variable leeren?

Danke,
Horst

kummer
Beiträge: 2423
Registriert: Do 6. Mai 2004, 09:17
Wohnort: Bern, Schweiz
Kontaktdaten:

Re: eval()'d code

Beitrag von kummer » Fr 30. Apr 2010, 16:04

Horst Wiese hat geschrieben:wie mach ich das, diese Variable leeren?
wenn das über das backend nicht mehr möglich ist, musst du das direkt in phpmyadmin vornehmen. also zuerst die idartlang des artikels ermitteln (= x). dann mit dieser idartlang in der con_content nach dieser idartlang recherchieren. der eintrag mit idtype = 2 und typeid = 2 und idartlang = x müsste der entsprechende eintrag sein.

ich hatte übrigens solche vorfälle auch schon. das zeigt eigentlich gut, dass das verfahren der ersetzung und evaluierung schlecht geeignet ist und fast zwangsläufig zu solchen problemen führt. der inhalt aus der con_content dürfte unter keinen umständen nochmals evaluiert werden. will heissen, anstatt den inhalt einer variablen innerhalb des evaluierten codes zuzuweisen, müsste dieser in einem objekt bereit gestellt werden, auf welches im code dann verwiesen wird. das wäre auch ganz einfach zu realisieren. ein "CMS_HTML[2]" müsste im code lediglich durch ein $oContent->get("CMS_HTML", 2, $idartlang) ersetzt werden. das objekt $oContent würde dann den bezeichneten Wert bereit stellen.
aitsu.org :: schnell - flexibel - komfortabel :: Version 2.2.0 (since June 22, 2011) (jetzt mit dual license GPL/kommerziell)

Horst Wiese
Beiträge: 28
Registriert: Do 28. Mai 2009, 06:55
Wohnort: Bremen

Re: eval()'d code

Beitrag von Horst Wiese » Mi 5. Mai 2010, 08:02

hallo kummer,

deine Idee hat leider auch nicht weitergeführt, aber ich habe das Problem auf eine mir vollkommen unverständliche Weise gelöst:
wie gesagt bedeutete der Aufruf von "CMS_HTML[2]" ein Problem, schließlich fand ich in einem vorherigen Modul auf dieser Seite
eine Auskommentierung im Code, die diese Varaible benutzte, als ich diese Auskommentierung gelöscht habe, war das Problem gelöst.

Leider habe ich den auskommentierten Code von gestern nicht mehr, aber auch heute trat das gleiche Problem, diesmal mit der Variablen
CMS_TEXT[3], auf, und wieder fand ich folgende Codezeile in einem Modul, das in der Seite vorher geladen wurde:

Code: Alles auswählen

    //$tpl->set('s', 'RECHTE_TEASERHEADLINE', "CMS_TEXT[3]");
Nach Löschen dieser Zeile lief alles wieder o.k.

Wie kann auskommentierter Code nach Upgrade 4.6.15 -> 4.8.12. zum Editorabsturz führen?

viele Grüße,
Horst

Oldperl
Beiträge: 4251
Registriert: Do 30. Jun 2005, 22:56
Wohnort: Eltmann, Unterfranken, Bayern
Kontaktdaten:

Re: eval()'d code

Beitrag von Oldperl » Mi 5. Mai 2010, 12:05

Horst Wiese hat geschrieben:Wie kann auskommentierter Code nach Upgrade 4.6.15 -> 4.8.12. zum Editorabsturz führen?
Weil Contenido beim Parsen der CMS_VAR nicht auf auskommentierte Codestellen achtet. Hier wäre es evtl. sinnvoll solchen auskommentierte Code vor der Weiterverarbeitung sogar anhand der Kommentarzeichen zu entfernen.

Ich denke das sollte man mal zu einem ToDo des Parsers hinzufügenen, auskommentierter PHP-Code könnte generell entfernt werden vor dem Parsen, so würde auch die con_code schrumpfen.

Das ist zwar nun nicht wirklich ein Bug, sondern für mich eher eine Verbesserung, trotzdem verschieb ich den Thread mal nach Bugs zur weiteren Bearbeitung. :-)

Gruß aus Franken

Ortwin
ConLite 2.1, alternatives und stabiles Update von Contenido 4.8.x unter PHP 7.x - Download und Repo auf Gitport.de
phpBO Search Advanced - das Suchwort-Plugin für CONTENIDO 4.9
Mein Entwickler-Blog

Oldperl
Beiträge: 4251
Registriert: Do 30. Jun 2005, 22:56
Wohnort: Eltmann, Unterfranken, Bayern
Kontaktdaten:

Re: eval()'d code

Beitrag von Oldperl » Do 6. Mai 2010, 17:11

Soderle, ich hab dann da mal was fertig gemacht.

:!: Es werden Änderungen am Corecode gemacht, bitte an Backups denken und nicht in produktiven Umgebungen ohne ausreichende Tests einsetzen. :!:

Na dann mal los. :wink:
Öffne die Datei contenido/includes/functions.con2.php in deinem bevorzugten Editor und füge folgende Codezeile am Ende ein

Code: Alles auswählen

/**
 * strips all comments from a given PHP code
 *
 * @param string $code
 * @return string
 *
 * @version 1.0
 * @author Ortwin Pinke
 * @copyright Ortwin Pinke <www.ortwinpinke.de>
 * @license LGPL
 */
function dceStripAllComments($code) {
    $sNewCode = '';
    $aTokens2Strip = array(T_COMMENT,T_CHARACTER);
    if (defined('T_DOC_COMMENT')) $aTokens2Strip[] = T_DOC_COMMENT;
    if (defined('T_ML_COMMENT')) $aTokens2Strip[] = T_ML_COMMENT;

    $aTmpTokens = token_get_all($code);

    foreach($aTmpTokens as $token) {
        if(is_array($token)) {
            if(in_array($token[0], $aTokens2Strip)) continue;
            $token = $token[1];
        }
        $sNewCode .= $token;
    }
    return $sNewCode;
}
Nun suche folgenden Code bei Zeile 286

Code: Alles auswählen

$output = $thisModule.$thisContainer.$db->f("output");
und ändere in zu

Code: Alles auswählen

$output = $thisModule.$thisContainer.dceStripAllComments($db->f("output"));
Fertig!

Zur Erklärung: Die Funktion entfernt alle Kommentare aus einem gegebenen PHP-Code. In diesem Fall bei der Erzeugung des Codes für das Frontend, welcher dann auch in der con_code landet, für alle eingesetzen Modul-Outputs. Hierbei entstehen gleich mehrere Vorteile.
  1. Alle weitere Aktionen beim Parsen der Module verwenden weniger Resourcen, sowohl zeitlich als auch beim RAM.
  2. Der in con_code gecachte Code wird teilweise weit über ein Drittel geschrumpft.
  3. Die Ladezeit bei der SQL-Anfrage des Frontends verringert sich, und damit auch die Serverlast für MySQL
  4. Die Ausführungszeit dieses Codes in der front_content.php per eval() verringert sich ebenfalls.
Es ist sicherlich erst mal ein kleiner Schritt zu einem schneller Frontend, da steckt noch einiges an Arbeit drin. Aber es zeigt sich dadurch eine spürbare Verbesserung sowohl der Geschwindigkeit als auch der Serverlast. Und es steckt noch sehr viel Potential in einer Verbesserung der Codegenerierung.

Ich möchte euch bitten diese Modifikation mal zu testen, wenn möglich auch mal im Vergleich "Vorher-Nachher". Danke. :-)

Gruß aus Franken

Ortwin
ConLite 2.1, alternatives und stabiles Update von Contenido 4.8.x unter PHP 7.x - Download und Repo auf Gitport.de
phpBO Search Advanced - das Suchwort-Plugin für CONTENIDO 4.9
Mein Entwickler-Blog

kummer
Beiträge: 2423
Registriert: Do 6. Mai 2004, 09:17
Wohnort: Bern, Schweiz
Kontaktdaten:

Re: eval()'d code

Beitrag von kummer » Sa 8. Mai 2010, 11:52

Ich vermute mal, der Leistungszuwachs wird nicht zu bemerken sein. Die auskommentierten Stellen werden ja ohnehin nicht ausgeführt und haben dadurch kaum Einfluss auf die Geschwindigkeit der Evaluation. Ausserdem dürften solche Stellen in einem Modul nicht - wie angenommen - einen Drittel des Gesamtcodes ausmachen. Für Klassen dürfte die Einschätzung stimmen. Für Module halte ich das für ausgeschlossen. Ähnliche Erwägungen gelten für die Ladezeiten des Codes aus der DB. Wenn du dir die Abfrage im Explain-Modus anschaust, wirst du feststellen, dass in erster Linie die Abfrage-Optimierung Zeit in Anspruch nimmt. Die Rückgabe des Codes fällt da kaum ins Gewicht.

Der Nutzen der con_code ist mir sowieso nicht ganz klar. Eigentlich sollte dieser ja eine Verbesserung der Leistung bringen. Aber das Gegenteil ist der Fall. Bypassed man die con_code, dann nimmt die Leistung zu.

Aber daneben müsste man sich überlegen, ob man das Verfahren - wenn man denn schon Änderungen vornimmt - nicht wirklich etwas verbessern will. Die Einfügung von Inhalten in den Code und die anschliessende Ausführung des resultierenden Codes ist grundsätzlich fehleranfällig. Dein Code mag ein Problem eliminiert haben. Ein nächstes wird kommen. Aber wenn man nun hingehen würde und die Auftreten von "CMS_HTML[X]" durch...

Code: Alles auswählen

$oCmsValue->html[X]
...ersetzen würde (welche den zutreffenden Wert dann ausgibt), hätte man gleich zwei Verbesserungen. Die beschriebenen Probleme würde es nicht mehr geben. Und zweitens könnte diese Schreibweise direkt in Modulen verwendet werden und künftig könnte man dann auf die Ersetzung ganz verzichten. Auch das Auslesen von nicht benötigten Werten könnte vermieden werden, wenn diese nur gelesen werden, wenn die Klasse auch wirklich angesprochen wird.
aitsu.org :: schnell - flexibel - komfortabel :: Version 2.2.0 (since June 22, 2011) (jetzt mit dual license GPL/kommerziell)

Oldperl
Beiträge: 4251
Registriert: Do 30. Jun 2005, 22:56
Wohnort: Eltmann, Unterfranken, Bayern
Kontaktdaten:

Re: eval()'d code

Beitrag von Oldperl » Sa 8. Mai 2010, 12:28

kummer hat geschrieben:Ich vermute mal, ...
Danke für dein ausführliches Testen und deine produktive Kritik. 8)
Du kannst gerne deine Codeänderungen hier zur Diskussion stellen. :-)

Gruß aus Franken

Ortwin
ConLite 2.1, alternatives und stabiles Update von Contenido 4.8.x unter PHP 7.x - Download und Repo auf Gitport.de
phpBO Search Advanced - das Suchwort-Plugin für CONTENIDO 4.9
Mein Entwickler-Blog

kummer
Beiträge: 2423
Registriert: Do 6. Mai 2004, 09:17
Wohnort: Bern, Schweiz
Kontaktdaten:

Re: eval()'d code

Beitrag von kummer » Sa 8. Mai 2010, 15:02

Offensichtlich ist der verwendete Regex zur Recherche der zu ersetzenden Platzhalter falsch. Naheliegend in einem solchen Fall ist, den Regex dahingehend anzupassen, dass das korrigiert ist. Das wäre die Variante mit den geringsten zu erwartenden Nebeneffekten. Der Einbau eines negative lookbehind würde dieses spezifische Problem lösen. Dabei bleibt allerdings das Problem bestehen, dass Inhalte von Variablen innerhalb eines eval geparsed werden, ohne zu Beginn wissen zu können, was diese enthalten und folglich stets damit rechnen zu müssen, dass genau das angsprochene Problem erneut auftritt. Dieses wiederum könnte man dauerhaft lösen, wenn man eine Ersetzung durch eine Methode vornimmt, die erst im Rahmen der Ausführung die Rückgabe vornimmt. Damit könnte man dann auch langsam eine neue Variante einführen. Nämlich diese Methode in Modulen oder auch in Klassen einzusetzen, statt eine Ersetzung vorzunehmen. Neben einem Bug haben wir hier ein Designproblem vorliegen, welches angegangen werden muss, wenn eine echte Verbesserung erzielt werden soll.

Im Allgemeinen wird bei der Softwareentwicklung eine Problemdiskussion vor der Lösung vorgenommen. Es finden sich nun - zum Glück - Leute, die Ad-Hoc-Lösungen anbieten, die als Hotfix durchaus ein Problem beheben können, das brennt. Für die langfristige Entwicklung ist das jedoch dann ein Problem, wenn es im Anschluss dann nicht möglich ist, Lösungen zu etablieren, die das Problem im Kern angehen. Im vorliegenden Fall haben wir zwei mögliche Störeinflüsse. Das resultierende HTML kann sich so auf das Backend auswirken, so dass eine Editierung nicht mehr möglich ist und zweitens kann es durch das Parsing des Inhalts zum angsprochenen Problem kommen. Und für das zweite Problem haben wir eine unter vielen möglichen Ursachen durch die Entfernung von Kommentaren elimiert. Die anderen werden bleiben.

OT: Es würde diesem Forum gut anstehen, wenn insbesondere die Moderatoren um etwas Sachlichkeit bemüht wären. Dies bloss von anderen einzufordern reicht alleine nicht aus. Es muss sich dann niemand wundern, wenn diejenigen, die was beizutragen hätten, sich langsam verabschieden.

Nachtrag: Den Test des Leistungsgewinns habe ich mir tatsächlich verkniffen. Die Rückgabe des Codes - und das ist die einzige Stelle, an der du theoretisch einen Leistungsgewinn erzielen könntest - liegt weit unterhalb einer Millisekunde. Ein Profiling ergibt, dass MySQL zur Übertragung eines normalen con_codes ca. 0.020 ms benötigt. Lasse ich den ganzen Code weg und nehme nur die id, dann fällt der Wert auf 0.015 ms. Der theoretisch erzielbare Gewinn, wenn der Code nur aus Kommentaren bestehen würde, beträgt also 0.005 ms. Auf meinem Rechner benötigt Contenido für die Auslieferung einer Seite rund 400 ms. Dann beträgt der Leistungsgewinn gerade mal < 0.002 %.
aitsu.org :: schnell - flexibel - komfortabel :: Version 2.2.0 (since June 22, 2011) (jetzt mit dual license GPL/kommerziell)

Oldperl
Beiträge: 4251
Registriert: Do 30. Jun 2005, 22:56
Wohnort: Eltmann, Unterfranken, Bayern
Kontaktdaten:

Re: eval()'d code

Beitrag von Oldperl » Mo 10. Mai 2010, 07:46

kummer hat geschrieben:OT: Es würde diesem Forum gut anstehen, wenn insbesondere die Moderatoren um etwas Sachlichkeit bemüht wären. Dies bloss von anderen einzufordern reicht alleine nicht aus. Es muss sich dann niemand wundern, wenn diejenigen, die was beizutragen hätten, sich langsam verabschieden.
Stimmt, als Moderator sollte man versuchen sachlich zu bleiben. Nur ist ein Moderator auch nicht nur irgendein gefühlloser Klotz und mir geht langsam die Hutschnur hoch, wenn Leute Alles und Jeden kritisieren und selbst, auser dieser Kritik, nichts produktives mehr einbringen. Vielleicht sind ja auch diese ewigen Tiraden ein Grund dafür, das sich User immer mehr zurückhalten.
Daher werde ich mich an diesem unsinnigen Verhalten in Zukunft nicht mehr beteiligen, sondern solche, das Forum aufblähende, unnütze Beiträge vorerst mal ignorieren. :roll:

Ansonsten würde ich mir wünschen, und da stimme ich dir zu, das wieder mehr Sachlichkeit ins Forum einkehrt. Hier würde meiner Meinung nach schon viel helfen, wenn man sachbezogene Threads nicht durch kilometerlange Grundsatzdiskussionen unüberschaubar macht, sondern diese Diskussionen, mit einem Querverweis versehen, in den dafür vorgesehenen Foren führt :!:
Auch ein dauerndes "schlecht machen", aus welchen (eigennützigen) Gründen auch immer, halte ich für unangebracht und ebenfalls nicht förderlich für die Community.


Mit sachlichem Gruß aus Franken

Ortwin
ConLite 2.1, alternatives und stabiles Update von Contenido 4.8.x unter PHP 7.x - Download und Repo auf Gitport.de
phpBO Search Advanced - das Suchwort-Plugin für CONTENIDO 4.9
Mein Entwickler-Blog

kummer
Beiträge: 2423
Registriert: Do 6. Mai 2004, 09:17
Wohnort: Bern, Schweiz
Kontaktdaten:

Re: eval()'d code

Beitrag von kummer » Mo 10. Mai 2010, 09:38

Oldperl hat geschrieben:Ansonsten würde ich mir wünschen, und da stimme ich dir zu, das wieder mehr Sachlichkeit ins Forum einkehrt. Hier würde meiner Meinung nach schon viel helfen, wenn man sachbezogene Threads nicht durch kilometerlange Grundsatzdiskussionen unüberschaubar macht, sondern diese Diskussionen, mit einem Querverweis versehen, in den dafür vorgesehenen Foren führt :!:
Auch ein dauerndes "schlecht machen", aus welchen (eigennützigen) Gründen auch immer, halte ich für unangebracht und ebenfalls nicht förderlich für die Community.
Wer alles falsch verstehen will, dem steht nie was im Weg. Zu einer sachlichen Diskussion gehört eben, dass man Dinge beim Namen nennt. Das ist keineswegs persönlich. Wo kein Leistungsgewinn vorliegt, hilft es eben nichts, so zu tun als ob. Das ist zunächst kein Vorwurf, sondern bloss eine Feststellung. Du nimmst an, du würdest einen Leistungsgewinn erzielen; eine einfache Analyse ergibt dann halt, dass das ein Irrtum ist. Das kann vorkommen und ist alleine kein Problem. Ähnlich sieht es mit einer Problemlösung aus, die aus einer Vielfalt möglicher Ursachen eine herausgreift und diese umsschifft. Das mag ein Problem lösen und lässt alle anderen unberührt.

Ich habe darauf geantwortet, weil ich einen Vorschlag zu machen habe, wie man das Problem angehen kann. Man könnte nun hingehen und sich überlegen, ob das nicht ein möglicher Ansatz ist. Oder man könnte aufzeigen, weshalb das keine gute Lösung ist und einen besseren Vorschlag machen. Oder man kann es so machen, wie das hier leider oft der Fall ist: man ignoriert alles.

Den Vorwurf, nichts Produktives beizutragen, muss ich mir nicht gefallen lassen. Ich habe immer wieder Lösungen aufgezeigt und auch entwickelt. Ich habe aufgehört, diese Lösungen hier anzubieten, weil sie nie Eingang in den Kern gefunden haben. Für meine Kunden ist das ein Problem, für das ich eine Lösung suchen musste. Und ich habe eine gefunden.

Ich werde mir den Vorwurf immer wieder anhören müssen, dass meine Kritik persönlich sei. Wer meine Posts liest, wird indes feststellen, dass dem nicht so ist. Solange man jedoch Moderatoren im Forum hat, die nur Lob und Anerkennung wollen und keinen Gewinn in einer sachlichen Kritik sehen, wird es die Vorwürfe geben. Wer dann nach der Ursache sucht für jahrelangen Stillstand in der Entwicklung, wird vermutlich erkennen, dass Ignoranz einen nicht unwesentlichen Beitrag dazu leistet.

@Ortwin: Lehn' dich doch einen Moment zurück und versuche mal in Betracht zu ziehen, dass es mir möglicherweise nicht in erster Linie darum geht, dich anzugreifen. Sondern ich den Ansatz einfach für verfehlt halte und mir deshalb erlaube, eine alternative Lösung aufzuzeigen. Na? Tönt das nicht durchaus vernünftig? Ist vielleicht eine Überlegung Wert.
aitsu.org :: schnell - flexibel - komfortabel :: Version 2.2.0 (since June 22, 2011) (jetzt mit dual license GPL/kommerziell)

Gesperrt