Index: uspace/lib/posix/stdlib/strtold.c
===================================================================
--- uspace/lib/posix/stdlib/strtold.c	(revision 63fc51900e00186bc5fe7fcdffe35b1cedcc18f1)
+++ uspace/lib/posix/stdlib/strtold.c	(revision 5ee969234f7538769c6d915755c96eea7086b534)
@@ -53,5 +53,5 @@
 #endif
 
-// TODO: documentation
+// TODO: clean up, documentation
 
 // FIXME: ensure it builds and works on all platforms
@@ -238,5 +238,7 @@
 	/* digits before decimal point */
 	while (isdigit(str[i])) {
-		if (parsed_digits < PARSE_DECIMAL_DIGS) {
+		if (parsed_digits == 0 && str[i] == '0') {
+			/* Nothing, just skip leading zeros. */
+		} else if (parsed_digits < PARSE_DECIMAL_DIGS) {
 			significand *= DEC_BASE;
 			significand += str[i] - '0';
@@ -254,5 +256,8 @@
 		/* digits after decimal point */
 		while (isdigit(str[i])) {
-			if (parsed_digits < PARSE_DECIMAL_DIGS) {
+			if (parsed_digits == 0 && str[i] == '0') {
+				/* Skip leading zeros and decrement exponent. */
+				exponent--;
+			} else if (parsed_digits < PARSE_DECIMAL_DIGS) {
 				significand *= DEC_BASE;
 				significand += str[i] - '0';
@@ -282,5 +287,5 @@
 		}
 		
-		while (isdigit(str[i])) {
+		while (isdigit(str[i]) && exp < 65536) {
 			exp *= DEC_BASE;
 			exp += str[i] - '0';
@@ -306,5 +311,6 @@
 }
 
-static inline int hex_value(char ch) {
+static inline int hex_value(char ch)
+{
 	if (ch <= '9') {
 		return ch - '0';
@@ -312,4 +318,19 @@
 		return 10 + tolower(ch) - 'a';
 	}
+}
+
+/**
+ * @param val Integer value.
+ * @return How many leading zero bits there are. (Maximum is 3)
+ */
+static inline int leading_zeros(uint64_t val)
+{
+	for (int i = 3; i > 0; --i) {
+		if ((val >> (64 - i)) == 0) {
+			return i;
+		}
+	}
+	
+	return 0;
 }
 
@@ -345,8 +366,22 @@
 	/* digits before decimal point */
 	while (posix_isxdigit(str[i])) {
-		if (parsed_digits < PARSE_HEX_DIGS) {
+		if (parsed_digits == 0 && str[i] == '0') {
+			/* Nothing, just skip leading zeros. */
+		} else if (parsed_digits < PARSE_HEX_DIGS) {
 			significand *= HEX_BASE;
 			significand += hex_value(str[i]);
 			parsed_digits++;
+		} else if (parsed_digits == PARSE_HEX_DIGS) {
+			/* The first digit may have had leading zeros,
+			 * so we need to parse one more digit and shift
+			 * the value accordingly.
+			 */
+			
+			int zeros = leading_zeros(significand);
+			significand = (significand << zeros) |
+			    (hex_value(str[i]) >> (4 - zeros));
+			
+			exponent += (4 - zeros);
+			parsed_digits++;
 		} else {
 			exponent += 4;
@@ -361,8 +396,23 @@
 		/* digits after decimal point */
 		while (posix_isxdigit(str[i])) {
-			if (parsed_digits < PARSE_HEX_DIGS) {
+			if (parsed_digits == 0 && str[i] == '0') {
+				/* Skip leading zeros and decrement exponent. */
+				exponent -= 4;
+			} else if (parsed_digits < PARSE_HEX_DIGS) {
 				significand *= HEX_BASE;
 				significand += hex_value(str[i]);
 				exponent -= 4;
+				parsed_digits++;
+			} else if (parsed_digits == PARSE_HEX_DIGS) {
+				/* The first digit may have had leading zeros,
+				 * so we need to parse one more digit and shift
+				 * the value accordingly.
+				 */
+				
+				int zeros = leading_zeros(significand);
+				significand = (significand << zeros) |
+				    (hex_value(str[i]) >> (4 - zeros));
+				
+				exponent -= zeros;
 				parsed_digits++;
 			} else {
@@ -389,5 +439,5 @@
 		}
 		
-		while (isdigit(str[i])) {
+		while (isdigit(str[i]) && exp < 65536) {
 			exp *= DEC_BASE;
 			exp += str[i] - '0';
