Webstatt.org - Community seit 2006 - 2012 (2024?)

Regex Problem IMG und URL Tag

Avatar user-125
27.07.2007 11:21

Hallo,

ich hab vorhin ne Class geschrieben für BBCode.
Die Funktionen der Class, die die URLs und die IMG-Tags behandeln sind folgende:

function bblinks() {
// replace xyz
$this->string = preg_replace(
"=\[url\](.*)\[\/url\]=i",
"<a href=\"$1\">$1</a>",
$this->string
);
// replace text
$this->string = preg_replace(
"=\[url\=\"(.*)\](.*)\[\/url\]=i",
"<a href=\"$1\">$2</a>",
$this->string
);
// replace trext
$this->string = preg_replace(
"=\[url\='(.*)'\](.*)\[\/url\]=i",
"<a href=\"$1\">$2</a>",
$this->string
);
// replace text
$this->string = preg_replace(
"=\[url\=(.*)\](.*)\[\/url\]=i",
"<a href=\"$1\">$2</a>",
$this->string
);

}



function bbimages() {
if(preg_match_all("=\[img\](.*)\[\/img\]=Ui", $this->string, $matches)) {
$width = 'auto';
$height = 'auto';
foreach($matches['1'] AS $img) {
$img = strtolower($img);
$allowed = FALSE;
$url = substr($img, 0,4);
if($this->images_local && $url != 'http' ) {
$allowed = TRUE;
}
if($this->images_url && $url == 'http'zwinkern {
$allowed = TRUE;
}

if($this->images_dynamik) {
$url_end = substr($img, strlen($img)-3, 3);
if($url_end != 'jpg' && $url_end != 'gif' && $url_end != 'png'zwinkern {
if(substr($img, strlen($img)-4, 4) != 'jpeg'zwinkern {
$allowed = FALSE;
}
}
}

if($allowed) {
if($this->images_properties) {
if($this->images_only_local_properties) {
if($url != 'http'zwinkern {
$imagesize = getimagesize($img);
if($imagesize) {
$width = $imagesize['0'];
$height = $imagesize['1'];
}
}
} else {
$imagesize = getimagesize($img);
if($imagesize) {
$width = $imagesize['0'];
$height = $imagesize['1'];
}
}
}
$this->string = preg_replace(
"=\[img\]".$img."\[\/img\]=",
"<img src=\"".$img."\" alt=\"Image\" style=\"width:".$width.";height:".$height.";border:0px;\" />",
$this->string
);
} else {
$this->string = preg_replace(
"=\[img\]".$img."\[\/img\]=",
"<abbr title=\"Es wurde versucht ein Bild über die Adresse '".$img."' einzubinden.\">IMAGE</abbr> <a class=\"biglink\" href=\"".$img."\">".chr(129)."</a>",
$this->string
);
}
}
}
}


Aufruf
       function parse($string) {
$string = htmlspecialchars_decode($string);
$this->string = $string;

#if($this->basic)
#$this->bbbasics();

if($this->links)
$this->bblinks();

if($this->images)
$this->bbimages();


return $this->string;
}


Leider funktioniert ein IMG Tag im URL Tag nicht.
Also:

Geht leider nicht. Jemand ne Idee warum (Cix88 schüttelt sicher gerade dne Kopf zwinkern)

Liebe user-125y aka user-125 aka dionysos
Avatar user-194
27.07.2007 19:01

Rein aus "Lehrzwecken" hab ich deinen Code mal überarbeitet und zeige ihn dir hier...
class BB {
var $links = TRUE;
var $images = TRUE;
var $images_local = TRUE;
var $images_url = TRUE;

function bblinks() {
// replace xyz
$this->string = preg_replace('=\[url\](.*)\[/url\]=Ui',
'<a href="$1">$1</a>', $this->string);

// replace text, text
// and text
$this->string = preg_replace('!\[url=((?:\'|"|))(.+)\1'.
'\](.+)\[/url\]!i', '<a href="$2">$3</a>',
$this->string);
}

function bbimages() {
$this->string = preg_replace_callback(
'=\[img\](.+)\[\/img\]=Ui', array($this, 'bbimages_'zwinkern,
$this->string);
}

function bbimages_($m) {
$img = strtolower($m[1]);
$allowed = FALSE;
$scheme = explode('://', $img, 2);
// in anderen Sprachen ginge das direkt...
$scheme = $scheme[0];

// externe Bilder erlauben in alten IE-Versionen eventuell
// XSS! (der IE führt JS-Code auch be <img /> aus, wenn
// der Content-Type passt...
// evtl. lieber weglassen
if (($this->images_local && !$scheme) or
($this->images_url && $scheme == 'http'zwinkern) {
$allowed = TRUE;
}

// den ganzen "Dynamik"-Code hab ich weggelassen, keine Ahnung
// was das sollte?
if (!$allowed) {
return '<abbr title="Es wurde versucht ein Bild über'.
' die Adresse "'.htmlspecialchars($img).
'" einzubinden.">IMAGE</abbr> <a class="'.
'biglink" href="'.htmlspecialchars($img).
'">'.chr(129).'</a>';
}

$width = 'auto';
$height = 'auto';
if ($this->images_properties) {
if (!$this->images_only_local_properties or !$scheme) {
$imagesize = getimagesize($img);
if ($imagesize) {
$width = $imagesize[0];
$height = $imagesize[1];
}
}

}
return '<img src="'.htmlspecialchars($img).'" alt="Image"'.
' style="width:'.$width.';height:'.$height.
';border:0px;" />';
}


function parse($string) {
#$string = htmlspecialchars_decode($string); // ?
$this->string = $string;
#if($this->basic)
#$this->bbbasics();
if ($this->links) {
$this->bblinks();
}
if ($this->images) {
$this->bbimages();
}
return $this->string;
}
}

Das von dir genannte Problem tritt mit diesem Code nicht auf. Etliche andere Bugs sind damit behoben (u.a. XSS). Aber ganz ehrlich, ich würde diesen Code (und noch weniger den Original-Code) irgendwo einsetzen. Es gibt sicher noch etliche Fehler, die nicht so einfach zu beheben sind. Ein Beispiel wäre:
" target="_blank" class="link">

Resultat: Kaputtes HTML.
Benutz lieber ein gescheites fertiges System oder mach es selber richtig (das geht mit PCRE (alleine) einfach nicht, du musst da eine gewisse Logik wie bei einem echten Parser reinbringen -- eben kontextsensitiv).

Es wäre übrigens einfacher, wenn du das nächste mal den kompletten relevanten Code (in diesem Fall also zumindest noch das Grundgerüst der Klasse), aktuelles und erwartetes Resultat hinschreiben würdest.