diff --git a/contrib/unaccent/unaccent.c b/contrib/unaccent/unaccent.c
index 262d5ec15f8eab63f0e3c707e2f88a593568b92a..eabf01baf8293d4b6f584cc1d16770d7a254e08f 100644
--- a/contrib/unaccent/unaccent.c
+++ b/contrib/unaccent/unaccent.c
@@ -15,6 +15,7 @@
 
 #include "catalog/namespace.h"
 #include "commands/defrem.h"
+#include "lib/stringinfo.h"
 #include "tsearch/ts_cache.h"
 #include "tsearch/ts_locale.h"
 #include "tsearch/ts_public.h"
@@ -265,46 +266,48 @@ unaccent_lexize(PG_FUNCTION_ARGS)
 	SuffixChar *rootSuffixTree = (SuffixChar *) PG_GETARG_POINTER(0);
 	char	   *srcchar = (char *) PG_GETARG_POINTER(1);
 	int32		len = PG_GETARG_INT32(2);
-	char	   *srcstart,
-			   *trgchar = NULL;
-	int			charlen;
-	TSLexeme   *res = NULL;
-	SuffixChar *node;
+	char	   *srcstart = srcchar;
+	TSLexeme   *res;
+	StringInfoData buf;
+
+	/* we allocate storage for the buffer only if needed */
+	buf.data = NULL;
 
-	srcstart = srcchar;
 	while (srcchar - srcstart < len)
 	{
+		SuffixChar *node;
+		int			charlen;
+
 		charlen = pg_mblen(srcchar);
 
 		node = findReplaceTo(rootSuffixTree, (unsigned char *) srcchar, charlen);
 		if (node && node->replaceTo)
 		{
-			if (!res)
+			if (buf.data == NULL)
 			{
-				/* allocate res only if it's needed */
-				res = palloc0(sizeof(TSLexeme) * 2);
-				res->lexeme = trgchar = palloc(len * pg_database_encoding_max_length() + 1 /* \0 */ );
-				res->flags = TSL_FILTER;
+				/* initialize buffer */
+				initStringInfo(&buf);
+				/* insert any data we already skipped over */
 				if (srcchar != srcstart)
-				{
-					memcpy(trgchar, srcstart, srcchar - srcstart);
-					trgchar += (srcchar - srcstart);
-				}
+					appendBinaryStringInfo(&buf, srcstart, srcchar - srcstart);
 			}
-			memcpy(trgchar, node->replaceTo, node->replacelen);
-			trgchar += node->replacelen;
-		}
-		else if (res)
-		{
-			memcpy(trgchar, srcchar, charlen);
-			trgchar += charlen;
+			appendBinaryStringInfo(&buf, node->replaceTo, node->replacelen);
 		}
+		else if (buf.data != NULL)
+			appendBinaryStringInfo(&buf, srcchar, charlen);
 
 		srcchar += charlen;
 	}
 
-	if (res)
-		*trgchar = '\0';
+	/* return a result only if we made at least one substitution */
+	if (buf.data != NULL)
+	{
+		res = (TSLexeme *) palloc0(sizeof(TSLexeme) * 2);
+		res->lexeme = buf.data;
+		res->flags = TSL_FILTER;
+	}
+	else
+		res = NULL;
 
 	PG_RETURN_POINTER(res);
 }