$xNeTworKx: (PERL) Fehlermeldung im Errolog, aber wieso ?

Hallo,
Ich weis nicht warum, aber ich bekomme dauernd im Errolog die Meldung :
Use of uninitialized value in concatenation (.) or string at /home/www/doc/1264/hauptroot/meinedomain.com/forum/mailingliste.cgi line 75.
Das ist leider nicht das erste Script, bei dem dauernd diese Meldung kommt, aber worna liegt das. Ich poste mal das Script : (line 75 ist übrigens die Zeile, die das 2.Mal print <<EOF; (vor </table>) beinhaltet.

#!/usr/bin/perl -w

use strict;
use CGI;
my $query = new CGI;
my $url = 'http://localhost/forum/';

if ($query->param('action'))  {
my $forumname = $query->param('name');
my $email = $query->param('email');
my $abfrage = $query->param('janein');
my $error = 0;
my $auswahl = '';
     valid($error,$forumname,$email,$abfrage,$auswahl);
     if (!$error)  {
     savemail($forumname,$email,$abfrage);
     main();
     }  else  {
     main($forumname,$email,$auswahl);
     }
}  else  {
my ($forumname,$email,$auswahl) = ('') x 3;
main($forumname,$email,$auswahl);
}

sub main  {
my ($forumname,$email,$auswahl) = @_;
my $in = '';
print $query->header;
print <<EOF;
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
        "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<meta http-equiv="Content-Style-Type" content="text/css">
     <link rel="stylesheet" type="text/css" href="hauptdaten.css">
     <script src="hauptdatei.js" type="text/javascript">
     </script>
     <link rel="shortcut icon" href="favicon.ico">
      <title>---MEETINGPOINT---</title>
      </head>
   <body>
   <div id="nr1"></div>
   <div id="nr2"></div>
   <div style="position:absolute; top:64px; left:0px"><a href="mailingliste.cgi" onMouseOver="Bildwechsel(0,highlight2)" onMouseOut="Bildwechsel(0,normal2)"><img src="pics/maillistedark.gif" width="103" height="21" alt="Mailliste"></a></div>
   <div id="mainbar"></div>
   <div style="position:absolute; top:62px; left:107px"><a href="$url?action=showparty" onMouseOver="Bildwechsel(1,highlight3)" onMouseOut="Bildwechsel(1,normal3)"><img src="pics/partytermine.gif" width="80" height="26" alt="Partytermine"></a></div>
   <div style="position:absolute; top:62px; left:195px"><a href="$url?action=links" onMouseOver="Bildwechsel(2,highlight4)" onMouseOut="Bildwechsel(2,normal4)"><img src="pics/links.gif" width="68" height="26" alt="Links"></a></div>
   <div style="position:absolute; top:62px; left:267px"><a href="$url?action=faq" onMouseOver="Bildwechsel(3,highlight5)" onMouseOut="Bildwechsel(3,normal5)"><img src="pics/faq.gif" width="55" height="26" alt="FAQ"></a></div>
   <div style="position:absolute; top:62px; left:328px"><a href="$url" onMouseOver="Bildwechsel(4,highlight6)" onMouseOut="Bildwechsel(4,normal6)"><img src="pics/forumdark.gif" width="80" height="26" alt="Forum"></a></div>
   <div style="position:absolute; top:62px; left:418px"><a href="$url" onMouseOver="Bildwechsel(5,highlight7)" onMouseOut="Bildwechsel(5,normal7)"><img src="pics/zurueck.gif" width="92" height="26" alt="zurück"></a></div>
   <div style="position:absolute; top:95px; left:0px">
   <table style="border:0px; width:650px">
   <colgroup>
   <col width="350">
   <col width="300">
   </colgroup>
   <tr><td class="right">eingetragene Mitglieder</td><td class="left">Email Adressen</td></tr>
EOF
       if (-e 'maillist/mail.txt')  {
       open(FILE,'maillist/mail.txt') or die "Cant open mail-database : $!\n";
       local $/;
       $in = <FILE>;
       close FILE;
              while ($in =~ /<user>[name:(.+?)][email:(.+?)][abfrage:(.+?)]</user>/sg)  {
                     if ($3 eq 'ja')  {
      print "<tr><td class="orangeright"> $1 </td><td class="left"><a href="mailto:$2">$2</a></td></tr>\n";
      }  else  {
                     print "<tr><td class="orangeright"> $1 </td><td class="left"> Email Adresse verhüllt </td></tr>\n";
      }
              }
       }
print <<EOF;
   </table>
   <p>
      <form method="post" name="mailformular" action="" onSubmit="return chkmailform();">
      <table style="border:0px; width:700px">
      <colgroup>
      <col width="40%">
      <col width="60%">
      </colgroup>
      <tr><td class="right">Wie lautet dein Name im Forum ? </td><td><input class="party" type="text" name="name" value="$forumname" maxlength="150"></td></tr>
      <tr><td class="right">Wie lautet deine Email Adresse? </td><td><input class="party" type="text" name="email" value="$email" maxlength="100"></td></tr>
      <tr><td colspan="2" class="orangeright"> $auswahl </td></tr>
      <tr><td class="right">Soll die Email Adresse in der Liste angezeigt werden ?</td><td><input type="radio" name="janein" value="ja"> ja <input type="radio" name="janein" value="nein"> nein </td></tr>
      <tr><td>   </td><td><input type="submit" class="linkbutton" name="action" value="hinzufügen"></td></tr>
      </table>
   </form>
   </div>
   </body>
   </html>
EOF
}

sub savemail  {
my ($forumname,$email,$abfrage) = @_;
open(FILE,">>maillist/mail.txt") or die "Cant save data : $!\n";
flock FILE, 2;
print FILE "<user>[name:$forumname][email:$email][abfrage:$abfrage]</user>\n";
close FILE;
}

sub valid  {
my ($error,$forumname,$email,$abfrage,$auswahl) = @_;
     if (($$forumname eq '') || ($$forumname eq 'Es wurde kein Name eingetragen'))  { $$error = 1; $$forumname = 'Es wurde kein Name eingetragen'; }
     if (($$email !~ /.+?@.+?..{2,4}/) && ($$email ne ''))  {
     $$error = 1; $$email = 'Diese Email Adresse ist ungültig';
     }
     if ($$email eq '')  {
     $$error = 1; $$email = 'Es wurde keine Email Adresse eingetragen';
     }
     if ($$abfrage eq '')  { $$error = 1; $$auswahl = 'Es wurde nicht angegeben, ob die Email Adresse in der Liste angezeigt werden soll';  }
}

$xNeTworKx.

  1. hi,

    die fehlermeldung kommt meist, wenn eine variable falsch verwendet wird. zb wenn sie leer ist und es wird ein substr darauf gemacht.
    ich habe in der gegend der zeile 75 nichts ungwöhnliches entdeckt.

    das einzige, was mich stutzig macht ist, dass du zwei mal EOF als marke verwendest. das habe ich mir bisher noch nie erlaubt. weiss jetzt nicht, ob das erlaubt ist. aber versuch doch einmal sicherheitshalber, das zweite EOF in etwas anderes umzubenennen. natürlich an anfang und ende.

    grüssle
    bjoern

    1. Hi,

      die fehlermeldung kommt meist, wenn eine variable falsch verwendet wird. zb wenn sie leer ist und es wird ein substr darauf gemacht.
      ich habe in der gegend der zeile 75 nichts ungwöhnliches entdeckt.

      das einzige, was mich stutzig macht ist, dass du zwei mal EOF als marke verwendest. das habe ich mir bisher noch nie erlaubt. weiss jetzt nicht, ob das erlaubt ist. aber versuch doch einmal sicherheitshalber, das zweite EOF in etwas anderes umzubenennen. natürlich an anfang und ende.

      Hmmm daran liegts leider auch nicht. Es hat irgendwie mit Variablen zu tun, aber leider weis ich nicht wie.

      $xNeTworKx.

      1. Hi,

        Hmmm daran liegts leider auch nicht. Es hat irgendwie mit Variablen zu tun, aber leider weis ich nicht wie.

        wenn Du die Ursache eines Fehlers nicht selbst eingrenzen kannst: verändere das Script. Reduziere den Code auf (nichtstuende) Zeilen; versuche nur die minimal für den Fehler notwendige Struktur überzulassen. Dann findest Du die Ursache sehr schnell.

        Cheatah

        1. Hi,

          wenn Du die Ursache eines Fehlers nicht selbst eingrenzen kannst: verändere das Script. Reduziere den Code auf (nichtstuende) Zeilen; versuche nur die minimal für den Fehler notwendige Struktur überzulassen. Dann findest Du die Ursache sehr schnell.

          Das einzige, was ich weis, ist das die Meldung nur kommt, wenn eine Email Adresse gepostet wird. Sonst lasse ich mir bspw. immer mit print gewissen Stellen ausgeben, wenn ich ein Problem habe, aber das geht irgendwie hier nicht, da ich nicht weis, was den Fehler überhaupt verursacht, also welcher Bereich, besser gesagt.

          $xNeTworKx.

          1. Hi,

            dann liegt es wahrscheinlich am @.

            Ich habe so ein ähnliches Problem (siehe weiter unten "Was will mir diese Zeile sagen") und komm nicht dahinter.

            Greetings
            Torwächter

            1. Hi,

              dann liegt es wahrscheinlich am @.

              Wie meinst du das ?

              $xNeTworKx.

              1. Na wenn du ein @irgendwas eingibst, versteht Perl es als Befehl (Variable oder wie immer das ding sich nennt).
                Umgehen kannst du das mit /@ (also einem "/" vorm @)

                Greetings
                Torwächter

                1. Na wenn du ein @irgendwas eingibst, versteht Perl es als Befehl (Variable oder wie immer das ding sich nennt).
                  Umgehen kannst du das mit /@ (also einem "/" vorm @)

                  Huh ?
                  @irgendwas = das Array "irgendwas" und kein Befehl
                  ausserdem wenn ich @ escapen will, dann so @ .An dem liegt es aber nicht, sondern definitiv daran, daß eine uninitialisierte Variable verwendet wird (was mit use diagnostics und use warnings bestätigt) und die versuche ich nun zu finden.
                  Überhaupt verwende ich in meinem Script keine Arrays bis auf die Übergabe an die Sub. was aber nichts zur Sache tut.

                  1. ICH (glaub) HAB DEN FEHLER GEFUNDEN:

                    hinter !# perl... stand ein " -w" seit das weg ist wird aus dem Script kein Fehler mehr gemeldet.

                    Greetings
                    Torwächter

                    1. ICH (glaub) HAB DEN FEHLER GEFUNDEN:

                      hinter !# perl... stand ein " -w" seit das weg ist wird aus dem Script kein Fehler mehr gemeldet.

                      ja, der Fehler wird nicht mehr angezeigt, weil die Warnungen ausgeschaltet wurden, sonst nichts, aber da ist er noch immer. Solche Sachen bescheren dann leider nur unsichere CGI Scripts.

                      1. Das Ding is aber viel zu empfindlich, schon wenn eine variable (z.B. $test) in irgendeinem sub nicht zugeordnet wird, schreibt Apache ne Zeile.

                        Und ich halte eine nicht zugeordnete  Variable nicht für ein Sicherheitsrisiko, du ?

                        Greetings
                        Torwächter

                        1. Hi,

                          Und ich halte eine nicht zugeordnete  Variable nicht für ein
                          Sicherheitsrisiko, du ?

                          ohne weitere Angaben darüber, was diese Variable enthält? Ja.
                          Das Skript könnte ja diesen Inhalt als Systemkommando auszuführen
                          versuchen oder was auch immer.

                          Viele Grüße
                                Michael

                          1. Hallo,

                            ohne weitere Angaben darüber, was diese Variable enthält? Ja.
                            Das Skript könnte ja diesen Inhalt als Systemkommando auszuführen
                            versuchen oder was auch immer.

                            Naja, wenn es nur beim undef belieben würde, dann wäre es IMHO nicht so schlimm, da eine nicht definierte Variable sicherlich weniger Schaden anrichtet, als wenn sie eben etwas Böses als Wert hat.

                            Trotzdem stimme ich Dir zu, daß man nie ohne dem Sicherheitsgurt '-w' und dem Airbag 'use strict' unterwegs sein sollte, abgesehen davon, daß vorsichtig Fahren (== Eingangswerte, egal ob über CGI, Datei oder DB, prüfen) sowieso Pflicht ist.

                            Grüße
                              Klaus

                  2. Hi,

                    An dem liegt es aber nicht, sondern definitiv daran, daß eine uninitialisierte Variable verwendet wird (was mit use diagnostics und use warnings bestätigt) und die versuche ich nun zu finden.

                    eine Variable wie z.B. "@web", welche per "." mit "de" stringverknüpft (concatinated) werden soll? Tjaha, es ist schon sehr unwahrscheinlich, dass so etwas passiert, wenn irgendwo "hp@web.de" reingeschrieben wird... :-)

                    Jetzt musst Du "nur noch" herausfinden, wo genau und warum das passiert.

                    Cheatah

                    1. Hallo,

                      eine Variable wie z.B. "@web", welche per "." mit "de" stringverknüpft (concatinated) werden soll? Tjaha, es ist schon sehr unwahrscheinlich, dass so etwas passiert, wenn irgendwo "hp@web.de" reingeschrieben wird... :-)

                      Ok, jetzt ist es mir klar, nur wie kann ich das Problem umgehen ? Komisch irgendwie, das Perl die Eingabe interpretieren will.

                      $xNeTworKx.

  2. Hallo,

    valid($error,$forumname,$email,$abfrage,$auswahl);
         if (!$error)  {
         savemail($forumname,$email,$abfrage);
         main();

    Hier wird main() ohne Parameter aufgerufen, während sonst immer Parameter mit übergeben werden. Dadurch werden die korrespondierenden lokalen Variablen in main() mit undef befüllt, was zu genannter Warung führt.
    Mit einer Typisierung der Funktion währe Dir das nicht passiert.

    Übrigens macht es IMHO wenig Sinn, Variablen mit Referenzen zu übergeben, wenn Du sie eigentlich gar nicht ändern willst, so wie Du es mit valid() machst. Nicht nur, daß deren Handling komplizierter wird, es besteht auch die Gefahr sie versehentlich zu modifizieren, was dieser Funktion augenscheinlich nicht zusteht. Außerdem können Funktionen auch Rückgabewerte haben. In der genannten Funktion könnte dies $error sein. Bei geeigneter Wahl des Funktionsnamen und des Rückgabewertes kann das zu schönen Konstrukten führen.
    Bei deinem Beispiel könnte das so aussehen:
    ...
    wobei mir noch etwas auffällt.
    main() soll eigentlich immer aufgerufen, es ist daher nicht sinnvoll, diesen Aufruf auch mehrfach zu kodieren. Und die Variableninitialisierung könnte auch einfacher sein.
    Nach etwas ummodel sieht mein Vorschlag dann so aus:

    my $error = '';
    my ($forumname,$email,$auswahl) = ('','','');

    my$forumname = $query->param('name')||'';
    my $email = $query->param('email')||'';
    my $abfrage = $query->param('janein')||'';
    my $auswahl = '';
    if (($query->param('action') and ($error = valid($forumname,$email,$abfrage,$auswahl))){
     savemail($forumname,$email,$abfrage)
     }
    main($forumname,$email,$auswahl);

    HTH
     Klaus

    1. Hi,

      Hier wird main() ohne Parameter aufgerufen, während sonst immer Parameter mit übergeben werden. Dadurch werden die korrespondierenden lokalen Variablen in main() mit undef befüllt, was zu genannter Warung führt.
      Mit einer Typisierung der Funktion währe Dir das nicht passiert.

      Ich habe zur Probe mal main() so aufgerufen &main;, aber die Meldung kommt trotzdem. Ich glaube es ist so wie Cheatah sagt.

      Übrigens macht es IMHO wenig Sinn, Variablen mit Referenzen zu übergeben, wenn Du sie eigentlich gar nicht ändern willst, so wie Du es mit valid() machst. Nicht nur, daß deren Handling komplizierter wird, es besteht auch die Gefahr sie versehentlich zu modifizieren, was dieser Funktion augenscheinlich nicht zusteht. Außerdem können Funktionen auch Rückgabewerte haben. In der genannten Funktion könnte dies $error sein. Bei geeigneter Wahl des Funktionsnamen und des Rückgabewertes kann das zu schönen Konstrukten führen.
      Bei deinem Beispiel könnte das so aussehen:
      ...
      wobei mir noch etwas auffällt.
      main() soll eigentlich immer aufgerufen, es ist daher nicht sinnvoll, diesen Aufruf auch mehrfach zu kodieren. Und die Variableninitialisierung könnte auch einfacher sein.
      Nach etwas ummodel sieht mein Vorschlag dann so aus:

      my $error = '';
      my ($forumname,$email,$auswahl) = ('','','');

      my$forumname = $query->param('name')||'';
      my $email = $query->param('email')||'';
      my $abfrage = $query->param('janein')||'';
      my $auswahl = '';
      if (($query->param('action') and ($error = valid($forumname,$email,$abfrage,$auswahl))){
      savemail($forumname,$email,$abfrage)
      }
      main($forumname,$email,$auswahl);

      Hmmmm ja da müsste ich ja $error erst wieder zerlegen, und dann die verschiedenen Value's des Formulars mit den Werten füllen, aber ich werde mir das Konstrukt merken, so wie es ist.

      $xNeTworKx

      1. Hallo,

        Ich habe zur Probe mal main() so aufgerufen &main;, aber die Meldung kommt trotzdem. Ich glaube es ist so wie Cheatah sagt.

        Ich hab's gerade mal bei mir ausprobiert. Wenn Du, so wie es ist, mit main() aufruftst, dann kommt eine Warnung, wenn Du allerdings an dieser Stelle main('','','') verwendest, dann nicht. Eine Warung kommt übrigens auch, wenn nicht alle Felder ausgefüllt werden, dann allerdfings in der Funktion valid(). Du solltest berücksichtigen, daß $query->param('name') undef liefert, sollte der Parameter nicht übergeben worden sein, wie es z.B. in diesem Falle bei den Radiobuttons sein kann.

        Hmmmm ja da müsste ich ja $error erst wieder zerlegen, und dann die verschiedenen Value's des Formulars mit den Werten füllen, aber ich werde mir das Konstrukt merken, so wie es ist.

        Ich hätte mir den Code von valid() doch noch genauer ansehen sollen. Da werden $forumname,$email und $auswahl ja doch verändert. Dann sind Referenzen natürlich besser.
        Allerdings bin ich der Meinung, daß man Fehlermeldungen und Daten nicht mixen sollte. Warum führst Du nicht eine Fehlertextvariable mit, in der Du alle Fehler, die auftreten, sammelst um sie dann mit auszugeben.
        Wenn Du die Eingabewerte mit einer Fehlermeldung überschreibst, dann hat der Besuche ja keien Chance, seine Daten einfach zu korrigieren, sondern muß alles wieder neu eingeben. Wenn das nicht lästig ist.

        Grüße
          Klaus

        1. Hi,

          Wenn Du die Eingabewerte mit einer Fehlermeldung überschreibst, dann hat der Besuche ja keien Chance, seine Daten einfach zu korrigieren, sondern muß alles wieder neu eingeben. Wenn das nicht lästig ist.

          Naja, falls was vergessen wird, einzugeben, dann wird auch nichts überschrieben =). Gerade mal bei der Email Adresse ist es so wie du sagst, aber ich glaube, das ist akzeptabel. Ausserdem wird sowieso die Überprüfung auch noch mit JavaScript gemacht. Die Pwerl Überprüfung ist ja wirklich nur da, falls jemand JavaScript deaktiviert hat.
          Na  gut, das mit den Werten werde ich jetzt mal ausprobieren.

          $xNeTworKx.

          1. Hi nochmal,
            du hast Recht. Es klappt so. Ehrlich gesagt wäre ich da in 100 Jahren nicht draufgekommen :), daß es daran liegt. danke.

            $xNeTworKx.

            1. Hallo,

              du hast Recht. Es klappt so. Ehrlich gesagt wäre ich da in 100 Jahren nicht draufgekommen :), daß es daran liegt. danke.

              Es ist doch so einfach. Javascript deaktivieren, signifikante Werte[1] eingeben, 'tail -f /path/to/error.log' in der Konsole mitlaufen lassen, ansehen was passiert, und das quasi in Echtzeit;-)

              Grüße
                Klaus

              [1] z.B. nichts oder 'sdkhkfsdkhsdkhdfk' .... *g*
              Bei Datenbankanbindungen sind auch Sachen wie Apostroph im String interessant.
              Da fällt mir ein. Was ist wenn jemand beim Forumnamen 'wasweisich][name:wasanderes' eingibt, bzw. überhaupt eckige Klammern?
              Da würde deine Regex, so befürchet ich, doch etwas ins trudeln kommen.
              Sag' jetzt nicht, das passiert schon nicht. Eines der Grundgesetze des Universums ist 'Was passieren kann, passiert auch'.

              1. Hi,

                du hast Recht. Es klappt so. Ehrlich gesagt wäre ich da in 100 Jahren nicht draufgekommen :), daß es daran liegt. danke.

                Es ist doch so einfach. Javascript deaktivieren, signifikante Werte[1] eingeben, 'tail -f /path/to/error.log' in der Konsole mitlaufen lassen, ansehen was passiert, und das quasi in Echtzeit;-)

                huh, das kenn ich noch gar nicht :)

                Da fällt mir ein. Was ist wenn jemand beim Forumnamen 'wasweisich][name:wasanderes' eingibt, bzw. überhaupt eckige Klammern?
                Da würde deine Regex, so befürchet ich, doch etwas ins trudeln kommen.

                Hmmm, hab es jetzt ausprobiert mit einem [ und mal ] mit " gemischt, aber er zeigt alles brav an, wie es soll, obwohl ich eigentlich zuerst etwas nachdenklich geworden bin.

                Sag' jetzt nicht, das passiert schon nicht. Eines der Grundgesetze des Universums ist 'Was passieren kann, passiert auch'.

                Ich schaue natürlich darauf ,daß jemand sowenig Unsinn machen kann wie nur geht. Normalerweise benutze ich <name>.+?</name>. Ich weis auch nicht, warum ich diesmal [name:  ] genommen habe. Ist aber nur in diesem Script jetzt so.

                Wundert mich aber wirklich, daß test1]test2]test3]ohne Probleme richtig angezeigt wird ?

                $xNeTworKx.

                1. Hallo,

                  Hmmm, hab es jetzt ausprobiert mit einem [ und mal ] mit " gemischt, aber er zeigt alles brav an, wie es soll, obwohl ich eigentlich zuerst etwas nachdenklich geworden bin.

                  Und was ist z.B. mit 'test][email:mist' im ersten Feld?

                  Ich weiß schon, man muß Dein Dateiformat kennen, um es auch aushebeln zu können, aber was passierten ... ach, das sagte ich ja schon *g*.

                  Grüße
                    Klaus

                  1. Hi,

                    Hmmm, hab es jetzt ausprobiert mit einem [ und mal ] mit " gemischt, aber er zeigt alles brav an, wie es soll, obwohl ich eigentlich zuerst etwas nachdenklich geworden bin.

                    Und was ist z.B. mit 'test][email:mist' im ersten Feld?

                    Oops :)

                    $xNeTworKx.