Index: src/htmltokenizer.c
===================================================================
--- src/htmltokenizer.c	(revision 8604)
+++ src/htmltokenizer.c	(working copy)
@@ -1050,6 +1050,7 @@
 	p->dest = p->buffer;
 			
 	p->tag = FALSE;
+	p->aTag = FALSE;
 	p->pending = NonePending;
 	(*src)++;
 			
@@ -1095,9 +1096,6 @@
 	}
 	else if (strncmp (p->buffer + 2, "tablesdkl", 9) == 0) {
 		html_tokenizer_blocking_push (t, Table);
-	}	
-	else if (strncmp (p->buffer + 2, "/a", 2) == 0) {
-		p->aTag = FALSE;
 	}
 	else {
 		if (p->blocking) {
@@ -1166,7 +1164,7 @@
 		if (t->priv->discard == NoneDiscard)
 			t->priv->pending = SpacePending;
 		ptr = t->priv->buffer;
-		if (ptr[1] == '<' && ptr[2] == 'a' && strlen (ptr) == 3)
+		if (strlen (ptr) == 3 && ptr[1] == '<' && ptr[2] == 'a')
 			t->priv->aTag = TRUE;
 	}
 	else if (t->priv->pre || t->priv->textarea) {
Index: src/ChangeLog
===================================================================
--- src/ChangeLog	(revision 8604)
+++ src/ChangeLog	(working copy)
@@ -1,3 +1,21 @@
+2007-10-24  Milan Crha  <mcrha@redhat.com>
+
+	** Fix for bug #485700
+
+	* htmltext.c: (html_link_set_url_and_target), (html_link_new):
+	Always escape amps when creating new/changing links.
+	* htmlobject.c: (html_object_get_complete_url):
+	Always unescape amps when returning complete urls.
+	* gtkhtml.c: (set_pointer_url):
+	Always unescape amps when storing pointer_url.
+	* htmlutils.h:
+	* htmlutils.c: (html_utils_maybe_escape_amp),
+	(html_utils_maybe_unescape_amp):
+	New source files to store utility functions.
+	* Makefile.am: Add new source files.
+	* htmltokenizer.c: (end_tag): Always unset priv->aTag when at the end
+	of tag to parse escaped sequences correctly.
+
 2007-10-24  Milan Crha  <mcrha@redhat.com>
 
 	** Fix for bug #488167
Index: src/htmltext.c
===================================================================
--- src/htmltext.c	(revision 8604)
+++ src/htmltext.c	(working copy)
@@ -49,6 +49,7 @@
 #include "htmlsettings.h"
 #include "htmltextslave.h"
 #include "htmlundo.h"
+#include "htmlutils.h"
 
 HTMLTextClass html_text_class;
 static HTMLObjectClass *parent_class = NULL;
@@ -3506,8 +3507,8 @@
 	g_free (link->url);
 	g_free (link->target);
 
-	link->url = g_strdup (url);
-	link->target = g_strdup (target);
+	link->url = html_utils_maybe_escape_amp (url);
+	link->target = html_utils_maybe_escape_amp (target);
 }
 
 Link *
@@ -3548,8 +3549,8 @@
 {
 	Link *link = g_new0 (Link, 1);
 
-	link->url = g_strdup (url);
-	link->target = g_strdup (target);
+	link->url = html_utils_maybe_escape_amp (url);
+	link->target = html_utils_maybe_escape_amp (target);
 	link->start_offset = start_offset;
 	link->end_offset = end_offset;
 	link->start_index = start_index;
Index: src/htmlutils.c
===================================================================
--- src/htmlutils.c	(revision 0)
+++ src/htmlutils.c	(revision 0)
@@ -0,0 +1,104 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* This file is part of the GtkHTML library.
+
+   Copyright (C) 1999, 2000 Helix Code, Inc.
+   
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+   
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+   
+   You should have received a copy of the GNU Library General Public License
+   along with this library; see the file COPYING.LIB.  If not, write to
+   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.
+*/
+
+#include <glib.h>
+#include <string.h>
+
+#include "htmlutils.h"
+
+/**
+ * html_utils_maybe_escape_amp
+ * When find '&' in url which is not part of "&amp;", then will escape it
+ * to "&amp;". Always returns new pointer on url.
+ * @param url URL to try to escape ampersands in.
+ * @return New allocated memory with escaped ampersands. Should be freed with g_free.
+ **/
+gchar *
+html_utils_maybe_escape_amp (const gchar *url)
+{
+	gchar *buff;
+	int amps, i, j;
+
+	if (!url)
+		return NULL;
+
+	amps = 0;
+	for (i = 0; url [i]; i++) {
+		if (url [i] == '&' && strncmp (url + i, "&amp;", 5) )
+			amps++;
+	}
+
+	if (!amps)
+		return g_strdup (url);
+
+	buff = g_malloc (sizeof (gchar) * (1 + i + 4 * amps));
+
+	for (i = 0, j = 0; url [i]; i++, j++) {
+		buff [j] = url [i];
+
+		if (url [i] == '&' && strncmp (url + i, "&amp;", 5) ) {
+			buff [j + 1] = 0;
+			strcat (buff + j, "amp;");
+			j += 4;
+		}
+	}
+
+	buff [j] = 0;
+
+	return buff;
+}
+
+/**
+ * html_utils_maybe_unescape_amp
+ * This will unescape "&amp;" to "&" if necessary. Always returns new pointer on url, so free it with g_free.
+ * @param url URL where to unescape "&amp;" sequences.
+ * @return Newly allocated memory with unescaped ampersands. Should be freed with g_free.
+ **/
+gchar *
+html_utils_maybe_unescape_amp (const gchar *url)
+{
+	gchar *buff;
+	int i, j, amps;
+
+	if (!url)
+		return NULL;
+
+	amps = 0;
+	for (i = 0; url [i]; i++) {
+		if (url [i] == '&' && strncmp (url + i, "&amp;", 5) == 0)
+			amps++;
+	}
+
+	buff = g_strdup (url);
+
+	if (!amps)
+		return buff;
+
+	for (i = 0, j = 0; url [i]; i++, j++) {
+		buff [j] = url [i];
+
+		if (url [i] == '&' && strncmp (url + i, "&amp;", 5) == 0)
+			i += 4;
+	}
+	buff [j] = 0;
+
+	return buff;
+}
Index: src/htmlutils.h
===================================================================
--- src/htmlutils.h	(revision 0)
+++ src/htmlutils.h	(revision 0)
@@ -0,0 +1,28 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*  htmlutils.h
+
+    Copyright (C) 1999 Helix Code, Inc.
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#ifndef _HTMLUTILS_H
+#define _HTMLUTILS_H
+
+gchar *html_utils_maybe_escape_amp (const gchar *url);
+gchar *html_utils_maybe_unescape_amp (const gchar *url);
+
+#endif /* _HTMLUTILS_H */
Index: src/Makefile.am
===================================================================
--- src/Makefile.am	(revision 8604)
+++ src/Makefile.am	(working copy)
@@ -128,6 +128,7 @@
 	htmliframe.c				\
 	htmlframe.c				\
 	htmlframeset.c				\
+	htmlutils.c				\
 	gtkhtml-compat.h			\
 	gtkhtml-keybinding.h			\
 	gtkhtml-private.h			\
@@ -202,6 +203,7 @@
 	htmliframe.h				\
 	htmlframe.h				\
 	htmlframeset.h				\
+	htmlutils.h				\
 	htmlengine-edit-table.h			\
 	$(PLATFORM_DEP_SOURCES)			\
 	$(NULL)
Index: src/htmlobject.c
===================================================================
--- src/htmlobject.c	(revision 8604)
+++ src/htmlobject.c	(working copy)
@@ -47,6 +47,7 @@
 #include "htmlrule.h"
 #include "htmltype.h"
 #include "htmlsettings.h"
+#include "htmlutils.h"
 
 #include "gtkhtmldebug.h"
 
@@ -1173,11 +1174,16 @@
 html_object_get_complete_url (HTMLObject *o, gint offset)
 {
 	const gchar *url, *target;
+	gchar *url2, *url3;
 
 	url = html_object_get_url (o, offset);
 	target = html_object_get_target (o, offset);
-	return url || target ? g_strconcat (url ? url : "#", url ? (target && *target ? "#" : NULL) : target,
-					      url ? target : NULL, NULL) : NULL;
+	url2 = url || target ? g_strconcat (url ? url : "#", url ? (target && *target ? "#" : NULL) : target,
+					    url ? target : NULL, NULL) : NULL;
+	url3 = html_utils_maybe_unescape_amp (url2);
+	g_free (url2);
+
+	return url3;
 }
 
 const gchar *
Index: src/gtkhtml.c
===================================================================
--- src/gtkhtml.c	(revision 8604)
+++ src/gtkhtml.c	(working copy)
@@ -64,6 +64,7 @@
 #include "htmltextslave.h"
 #include "htmlselection.h"
 #include "htmlundo.h"
+#include "htmlutils.h"
 
 #include "gtkhtml.h"
 #include "gtkhtml-embedded.h"
@@ -1261,7 +1262,7 @@
 		return;
 		
 	g_free (html->pointer_url);
-	html->pointer_url = url ? g_strdup (url) : NULL;
+	html->pointer_url = html_utils_maybe_unescape_amp (url);
 	g_signal_emit (html,  signals[ON_URL], 0, html->pointer_url);
 }
 
