Index: kernel/generic/src/lib/string.c
===================================================================
--- kernel/generic/src/lib/string.c	(revision 32704cb4dbae5f6cf8c7e510153454648b83135e)
+++ kernel/generic/src/lib/string.c	(revision b54d2f177d73478c2fc4d1d122eddfecc7393b6d)
@@ -60,6 +60,7 @@
  *
  * Decode a single UTF-8 character from a plain char NULL-terminated
- * string. Decoding starts at @index and this index is incremented
- * if the current UTF-8 string is encoded in more than a single byte.
+ * string. Decoding starts at @index and this index is moved to the
+ * beginning of the next character. In case of decoding error,
+ * index advances. However, index is never moved beyond (str+limit).
  *
  * @param str   Plain character NULL-terminated string.
@@ -79,8 +80,8 @@
 	int cbytes;		/* Number of continuation bytes. */
 
-	if (*index > limit)
+	if (*index + 1 > limit)
 		return invalch;
 
-	b0 = (uint8_t) str[*index];
+	b0 = (uint8_t) str[(*index)++];
 
 	/* Determine code length. */
@@ -115,6 +116,5 @@
 	/* Decode continuation bytes. */
 	while (cbytes > 0) {
-		b = (uint8_t) str[*index + 1];
-		++(*index);
+		b = (uint8_t) str[(*index)++];
 
 		/* Must be 10xxxxxx. */
@@ -135,6 +135,6 @@
  * Encode a single UTF-32 character as UTF-8 and store it into
  * the given buffer at @index. Encoding starts at @index and
- * this index is incremented if the UTF-8 character takes
- * more than a single byte.
+ * this index is moved at the position where the next character
+ * can be written to.
  *
  * @param ch    Input UTF-32 character.
@@ -157,5 +157,5 @@
 	int i;
 
-	if (*index > limit)
+	if (*index >= limit)
 		return false;
 
@@ -185,5 +185,5 @@
 
 	/* Check for available space in buffer. */
-	if (*index + cbytes > limit)
+	if (*index + cbytes >= limit)
 		return false;
 
@@ -198,5 +198,5 @@
 
 	/* Advance index. */
-	*index += cbytes;
+	*index += (1 + cbytes);
 	
 	return true;
@@ -220,11 +220,18 @@
 	size_t size = 0;
 	index_t index = 0;
-	
-	while ((utf8_decode(str, &index, UTF8_NO_LIMIT) != 0) && (size < count)) {
+	index_t iprev;
+	wchar_t ch;
+	
+	while (true) {
+		iprev = index;
+		if (size >= count)
+			break;
+		ch = utf8_decode(str, &index, UTF8_NO_LIMIT);
+		if (ch == '\0') break;
+
 		size++;
-		index++;
-	}
-	
-	return index;
+	}
+	
+	return iprev;
 }
 
@@ -284,5 +291,4 @@
 	while (utf8_decode(str, &index, UTF8_NO_LIMIT) != 0) {
 		size++;
-		index++;
 	}
 	
Index: kernel/generic/src/printf/printf_core.c
===================================================================
--- kernel/generic/src/printf/printf_core.c	(revision 32704cb4dbae5f6cf8c7e510153454648b83135e)
+++ kernel/generic/src/printf/printf_core.c	(revision b54d2f177d73478c2fc4d1d122eddfecc7393b6d)
@@ -258,5 +258,5 @@
 	if (precision == 0)
 		precision = size;
-	
+
 	count_t counter = 0;
 	width -= precision;
@@ -267,5 +267,5 @@
 		}
 	}
-	
+
 	int retval;
 	size_t bytes = utf8_count_bytes(str, min(size, precision));
@@ -279,5 +279,5 @@
 			counter++;
 	}
-	
+
 	return ((int) counter);
 }
@@ -586,4 +586,5 @@
 {
 	index_t i = 0;  /* Index of the currently processed character from fmt */
+	index_t nxt = 0;
 	index_t j = 0;  /* Index to the first not printed nonformating character */
 	
@@ -592,5 +593,10 @@
 	int retval;           /* Return values from nested functions */
 	
-	while ((uc = utf8_decode(fmt, &i, UTF8_NO_LIMIT)) != 0) {
+	while (true) {
+		i = nxt;
+		uc = utf8_decode(fmt, &nxt, UTF8_NO_LIMIT);
+
+		if (uc == '\0') break;
+
 		/* Control character */
 		if (uc == '%') {
@@ -612,6 +618,6 @@
 			
 			do {
-				i++;
-				uc = utf8_decode(fmt, &i, UTF8_NO_LIMIT);
+				i = nxt;
+				uc = utf8_decode(fmt, &nxt, UTF8_NO_LIMIT);
 				switch (uc) {
 				case '#':
@@ -638,16 +644,19 @@
 			int width = 0;
 			if (isdigit(uc)) {
-				while ((uc = utf8_decode(fmt, &i, UTF8_NO_LIMIT)) != 0) {
+				while (true) {
+					width *= 10;
+					width += uc - '0';
+
+					i = nxt;
+					uc = utf8_decode(fmt, &nxt, UTF8_NO_LIMIT);
+					if (uc == '\0')
+						break;
 					if (!isdigit(uc))
 						break;
-					
-					width *= 10;
-					width += uc - '0';
-					i++;
 				}
 			} else if (uc == '*') {
 				/* Get width value from argument list */
-				i++;
-				uc = utf8_decode(fmt, &i, UTF8_NO_LIMIT);
+				i = nxt;
+				uc = utf8_decode(fmt, &nxt, UTF8_NO_LIMIT);
 				width = (int) va_arg(ap, int);
 				if (width < 0) {
@@ -661,19 +670,22 @@
 			int precision = 0;
 			if (uc == '.') {
-				i++;
-				uc = utf8_decode(fmt, &i, UTF8_NO_LIMIT);
+				i = nxt;
+				uc = utf8_decode(fmt, &nxt, UTF8_NO_LIMIT);
 				if (isdigit(uc)) {
-					while ((uc = utf8_decode(fmt, &i, UTF8_NO_LIMIT)) != 0) {
+					while (true) {
+						precision *= 10;
+						precision += uc - '0';
+
+						i = nxt;
+						uc = utf8_decode(fmt, &nxt, UTF8_NO_LIMIT);
+						if (uc == '\0')
+							break;
 						if (!isdigit(uc))
 							break;
-						
-						precision *= 10;
-						precision += uc - '0';
-						i++;
 					}
-				} else if (fmt[i] == '*') {
+				} else if (uc == '*') {
 					/* Get precision value from the argument list */
-					i++;
-					uc = utf8_decode(fmt, &i, UTF8_NO_LIMIT);
+					i = nxt;
+					uc = utf8_decode(fmt, &nxt, UTF8_NO_LIMIT);
 					precision = (int) va_arg(ap, int);
 					if (precision < 0) {
@@ -693,9 +705,9 @@
 				/* Char or short */
 				qualifier = PrintfQualifierShort;
-				i++;
-				uc = utf8_decode(fmt, &i, UTF8_NO_LIMIT);
+				i = nxt;
+				uc = utf8_decode(fmt, &nxt, UTF8_NO_LIMIT);
 				if (uc == 'h') {
-					i++;
-					uc = utf8_decode(fmt, &i, UTF8_NO_LIMIT);
+					i = nxt;
+					uc = utf8_decode(fmt, &nxt, UTF8_NO_LIMIT);
 					qualifier = PrintfQualifierByte;
 				}
@@ -704,9 +716,9 @@
 				/* Long or long long */
 				qualifier = PrintfQualifierLong;
-				i++;
-				uc = utf8_decode(fmt, &i, UTF8_NO_LIMIT);
+				i = nxt;
+				uc = utf8_decode(fmt, &nxt, UTF8_NO_LIMIT);
 				if (uc == 'l') {
-					i++;
-					uc = utf8_decode(fmt, &i, UTF8_NO_LIMIT);
+					i = nxt;
+					uc = utf8_decode(fmt, &nxt, UTF8_NO_LIMIT);
 					qualifier = PrintfQualifierLongLong;
 				}
@@ -735,5 +747,5 @@
 				
 				counter += retval;
-				j = i + 1;
+				j = nxt;
 				goto next_char;
 			case 'c':
@@ -749,5 +761,5 @@
 				
 				counter += retval;
-				j = i + 1;
+				j = nxt;
 				goto next_char;
 			
@@ -853,9 +865,8 @@
 			
 			counter += retval;
-			j = i + 1;
+			j = nxt;
 		}
 next_char:
-		
-		i++;
+		;
 	}
 	
Index: kernel/generic/src/printf/vprintf.c
===================================================================
--- kernel/generic/src/printf/vprintf.c	(revision 32704cb4dbae5f6cf8c7e510153454648b83135e)
+++ kernel/generic/src/printf/vprintf.c	(revision b54d2f177d73478c2fc4d1d122eddfecc7393b6d)
@@ -50,6 +50,5 @@
 	
 	while (index < size) {
-		putchar(utf8_decode(str, &index, size - 1));
-		index++;
+		putchar(utf8_decode(str, &index, size));
 		chars++;
 	}
@@ -78,5 +77,4 @@
 	while ((uc = utf8_decode(str, &index, UTF8_NO_LIMIT)) != 0) {
 		putchar(uc);
-		index++;
 		chars++;
 	}
Index: kernel/generic/src/printf/vsnprintf.c
===================================================================
--- kernel/generic/src/printf/vsnprintf.c	(revision 32704cb4dbae5f6cf8c7e510153454648b83135e)
+++ kernel/generic/src/printf/vsnprintf.c	(revision b54d2f177d73478c2fc4d1d122eddfecc7393b6d)
@@ -85,11 +85,8 @@
 		
 		while (index < size) {
-			wchar_t uc = utf8_decode(str, &index, size - 1);
-			
-			if (!utf8_encode(uc, data->dst, &data->len, data->size - 2))
+			wchar_t uc = utf8_decode(str, &index, size);
+
+			if (!utf8_encode(uc, data->dst, &data->len, data->size - 1))
 				break;
-			
-			data->len++;
-			index++;
 		}
 		
@@ -150,8 +147,7 @@
 		}
 		
-		if (!utf8_encode(str[index], data->dst, &data->len, data->size - 2))
+		if (!utf8_encode(str[index], data->dst, &data->len, data->size - 1))
 			break;
 		
-		data->len++;
 		index++;
 	}
