Bug 92880 - [libc] [patch] almost rewritten inet_network(3) function
Summary: [libc] [patch] almost rewritten inet_network(3) function
Status: Open
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: 6.0-STABLE
Hardware: Any Any
: Normal Affects Only Me
Assignee: freebsd-bugs mailing list
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-02-06 07:00 UTC by Andrey Simonenko
Modified: 2018-01-03 05:16 UTC (History)
0 users

See Also:


Attachments
file.diff (1.75 KB, patch)
2006-02-06 07:00 UTC, Andrey Simonenko
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Andrey Simonenko 2006-02-06 07:00:14 UTC
inet_network(3) function is not very safe, since it does not
make all checks before converting string to network address.

Rewritten version of inet_network() performs all checks (at least
which I expect to see) and according to Assembler code it takes
less space and should be a bit faster.

Rewritten version also does not allow white space character
at the end of parsed string.

How-To-Repeat: 
Here I insert a test program and output from this program (rewritten
version of inet_network() is called inet_network_new() here):

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>


static in_addr_t
inet_network_new(const char *cp)
{
	u_char c;
	int got_data;
	u_int base, dots;
	in_addr_t res, val;

	res = 0;
	dots = 0;

again:
	val = 0;
	got_data = 0;
	if (*cp == '0') {
		cp++;
		if (*cp == 'x' || *cp == 'X') {
			cp++;
			base = 16;
		} else {
			base = 8;
			got_data = 1;
		}
	} else
		base = 10;
	while ((c = *cp) != '\0') {
		if (isdigit(c)) {
			if (base == 8 && c > '7')
				return (INADDR_NONE);
			val = val * base + c - '0';
		} else if (base == 16 && isxdigit(c))
			val = (val << 4) + 10 - (islower(c) ? 'a' : 'A');
		else
			break;
		if (val > 0xff)
			return (INADDR_NONE);
		cp++;
		got_data = 1;
	}
	if (!got_data)
		return (INADDR_NONE);
	if (dots != 0)
		res <<= 8;
	res |= val;
	if (c == '.') {
		if (++dots == 4)
			return (INADDR_NONE);
		cp++;
		goto again;
	}
	if (c != '\0')
		return (INADDR_NONE);
	return (res);
}

int
main(void)
{
	size_t	len;
	in_addr_t addr;
	const char **addr_ptr;
	const char *addr_tbl[] = {
	    "0x12", "127.1", "127.1.2.3", "0x123456", "0x12.0x34",
	    "0x12.0x345", "1.2.3.4.5", "1..3.4", ".", "1.", ".1", "0x",
	    "0", "01.02.07.077", "0x1.23.045.0", "", " ", "bar", "1.2bar",
	    "1.", "ÊÃÕËÅÎ", "255.255.255.255", "x", "0X12", "078",
	    "1 bar", "127.0xfff", NULL };

	printf("STRING\t\t\tINET_NETWORK\tINET_NETWORK_NEW\n");
	for (addr_ptr = addr_tbl; *addr_ptr != NULL; ++addr_ptr) {
		printf("\"%s\"", *addr_ptr);
		len = strlen(*addr_ptr) + 2;
		if (len < 8)
			printf("\t\t\t");
		else if (len < 16)
			printf("\t\t");
		else
			printf("\t");
		addr = inet_network(*addr_ptr);
		if (addr == INADDR_NONE)
			printf("INADDR_NONE\t");
		else
			printf("0x%08x\t", addr);
		addr = inet_network_new(*addr_ptr);
		if (addr == INADDR_NONE)
			printf("INADDR_NONE\n");
		else
			printf("0x%08x\n", addr);
	}

	return 0;
}

STRING			INET_NETWORK	INET_NETWORK_NEW
"0x12"			0x00000012	0x00000012
"127.1"			0x00007f01	0x00007f01
"127.1.2.3"		0x7f010203	0x7f010203
"0x123456"		0x00000056	INADDR_NONE
"0x12.0x34"		0x00001234	0x00001234
"0x12.0x345"		0x00001245	INADDR_NONE
"1.2.3.4.5"		INADDR_NONE	INADDR_NONE
"1..3.4"		0x01000304	INADDR_NONE
"."			0x00000000	INADDR_NONE
"1."			0x00000100	INADDR_NONE
".1"			0x00000001	INADDR_NONE
"0x"			0x00000000	INADDR_NONE
"0"			0x00000000	0x00000000
"01.02.07.077"		0x0102073f	0x0102073f
"0x1.23.045.0"		0x01172500	0x01172500
""			0x00000000	INADDR_NONE
" "			0x00000000	INADDR_NONE
"bar"			INADDR_NONE	INADDR_NONE
"1.2bar"		INADDR_NONE	INADDR_NONE
"1."			0x00000100	INADDR_NONE
"ÊÃÕËÅÎ"		INADDR_NONE	INADDR_NONE
"255.255.255.255"	INADDR_NONE	INADDR_NONE
"x"			0x00000000	INADDR_NONE
"0X12"			0x00000012	0x00000012
"078"			0x00000040	INADDR_NONE
"1 bar"			0x00000001	INADDR_NONE
"127.0xfff"		0x00007fff	INADDR_NONE
Comment 1 Bruce Cran freebsd_committer 2009-03-23 21:35:59 UTC
Responsible Changed
From-To: freebsd-bugs->freebsd-net

Over to maintainer(s).
Comment 2 Andrey Simonenko 2011-01-21 14:12:49 UTC
My previous modification had one typo and did not work correctly
for IPv4 addresses given in `.' donation in hexadecimal form.

Here another one update:

1. Test program that shows difference between implementation of
   inet_network(3) from 9-CURRENT and my implementation.

2. Diff for the src/lib/libc/inet/inet_network.c file.

Look on output from the test program ("<---" shows different values):

STRING			INET_NETWORK	INET_NETWORK_NEW
"0x12"			0x00000012	0x00000012
"127.1"			0x00007f01	0x00007f01
"127.1.2.3"		0x7f010203	0x7f010203
"0x123456"		INADDR_NONE	INADDR_NONE
"0x12.0x34"		0x00001234	0x00001234
"0x12.0x345"		INADDR_NONE	INADDR_NONE
"1.2.3.4.5"		INADDR_NONE	INADDR_NONE
"1..3.4"		INADDR_NONE	INADDR_NONE
"."			INADDR_NONE	INADDR_NONE
"1."			INADDR_NONE	INADDR_NONE
".1"			INADDR_NONE	INADDR_NONE
"0x"			0x00000000	INADDR_NONE	<---
"0"			0x00000000	0x00000000
"01.02.07.077"		0x0102073f	0x0102073f
"0x1.23.045.0"		0x01172500	0x01172500
""			INADDR_NONE	INADDR_NONE
" "			INADDR_NONE	INADDR_NONE
" f"			INADDR_NONE	INADDR_NONE
"bar"			INADDR_NONE	INADDR_NONE
"1.2bar"		INADDR_NONE	INADDR_NONE
"1."			INADDR_NONE	INADDR_NONE
"=CA=C3=D5=CB=C5=CE"		INADDR_NONE	INADDR_NONE
"255.255.255.255"	INADDR_NONE	INADDR_NONE
"x"			INADDR_NONE	INADDR_NONE
"0X12"			0x00000012	0x00000012
"078"			INADDR_NONE	INADDR_NONE
"1 bar"			0x00000001	INADDR_NONE	<---
"127.0xabcd"		INADDR_NONE	INADDR_NONE
"128"			0x00000080	0x00000080
"0.1.2"			0x00000102	0x00000102
"0xff.010.23.0xa0"	0xff0817a0	0xff0817a0
"x10"			0x00000010	INADDR_NONE	<---
"X20"			0x00000020	INADDR_NONE	<---
"x10.x20"		0x00001020	INADDR_NONE	<---
"4294967297"		0x00000001	INADDR_NONE	<---
"0x10000000f"		0x0000000f	INADDR_NONE	<---
"040000000003"		0x00000003	INADDR_NONE	<---

Test program:

diff -ruNp inet_network_test.orig/Makefile inet_network_test/Makefile
--- inet_network_test.orig/Makefile	1970-01-01 03:00:00.000000000 +0300
+++ inet_network_test/Makefile	2011-01-21 12:48:48.000000000 +0200
@@ -0,0 +1,9 @@
+PROG=3Dinet_network
+
+NO_MAN=3Dtrue
+
+WARNS=3D6
+
+DEBUG_FLAGS=3D-g
+
+.include <bsd.prog.mk>
diff -ruNp inet_network_test.orig/inet_network.c inet_network_test/inet_n=
etwork.c
--- inet_network_test.orig/inet_network.c	1970-01-01 03:00:00.000000000 +=
0300
+++ inet_network_test/inet_network.c	2011-01-21 15:29:47.000000000 +0200
@@ -0,0 +1,105 @@
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static in_addr_t
+inet_network_new(const char *s)
+{
+	u_int base, dots;
+	in_addr_t res, val;
+	u_char c;
+	char got_data;
+
+	res =3D 0;
+	dots =3D 0;
+	for (;;) {
+		val =3D 0;
+		got_data =3D 0;
+		if (*s =3D=3D '0') {
+			s++;
+			if (*s =3D=3D 'x' || *s =3D=3D 'X') {
+				s++;
+				base =3D 16;
+			} else {
+				base =3D 8;
+				got_data =3D 1;
+			}
+		} else
+			base =3D 10;
+		while ((c =3D *s) !=3D '\0') {
+			if (isdigit(c)) {
+				if (base =3D=3D 8 && c > '7')
+					return (INADDR_NONE);
+				val =3D val * base + c - '0';
+			} else if (base =3D=3D 16 && isxdigit(c))
+				val =3D (val << 4) + c + 10 -
+				    (islower(c) ? 'a' : 'A');
+			else
+				break;
+			if (val > 0xff)
+				return (INADDR_NONE);
+			s++;
+			got_data =3D 1;
+		}
+		if (!got_data)
+			return (INADDR_NONE);
+		if (dots !=3D 0)
+			res <<=3D 8;
+		res |=3D val;
+		if (c !=3D '.')
+			break;
+		if (++dots =3D=3D 4)
+			return (INADDR_NONE);
+		s++;
+	}
+	return (c =3D=3D '\0' ? res : INADDR_NONE);
+}
+
+int
+main(void)
+{
+	const char *const addr_str_tbl[] =3D {
+	    "0x12", "127.1", "127.1.2.3", "0x123456", "0x12.0x34",
+	    "0x12.0x345", "1.2.3.4.5", "1..3.4", ".", "1.", ".1", "0x",
+	    "0", "01.02.07.077", "0x1.23.045.0", "", " ", " f", "bar",
+	    "1.2bar", "1.", "=CA=C3=D5=CB=C5=CE", "255.255.255.255", "x", "0X12=
", "078",
+	    "1 bar", "127.0xabcd", "128", "0.1.2", "0xff.010.23.0xa0",
+	    "x10", "X20", "x10.x20", "4294967297", "0x10000000f",
+	    "040000000003", NULL };
+	const char *const *addr_str;
+	size_t len;
+	in_addr_t addr1, addr2;
+
+	printf("STRING\t\t\tINET_NETWORK\tINET_NETWORK_NEW\n");
+	for (addr_str =3D addr_str_tbl; *addr_str !=3D NULL; ++addr_str) {
+		printf("\"%s\"", *addr_str);
+		len =3D strlen(*addr_str) + 2;
+		if (len < 8)
+			printf("\t\t\t");
+		else if (len < 16)
+			printf("\t\t");
+		else
+			printf("\t");
+		addr1 =3D inet_network(*addr_str);
+		if (addr1 =3D=3D INADDR_NONE)
+			printf("INADDR_NONE\t");
+		else
+			printf("0x%08x\t", addr1);
+		addr2 =3D inet_network_new(*addr_str);
+		if (addr2 =3D=3D INADDR_NONE)
+			printf("INADDR_NONE");
+		else
+			printf("0x%08x", addr2);
+		if (addr1 !=3D addr2)
+			printf("\t<---");
+		printf("\n");
+	}
+	return (0);
+}

Diff for src/lib/libc/inet/inet_network.c:

--- inet_network.c.orig	2008-01-15 00:55:20.000000000 +0200
+++ inet_network.c	2011-01-21 15:58:17.000000000 +0200
@@ -48,57 +48,56 @@ __FBSDID("$FreeBSD: src/lib/libc/inet/in
  * network numbers.
  */
 in_addr_t
-inet_network(cp)
-	const char *cp;
+inet_network(const char *s)
 {
-	in_addr_t val, base, n;
-	char c;
-	in_addr_t parts[4], *pp =3D parts;
-	int i, digit;
+	u_int base, dots;
+	in_addr_t res, val;
+	u_char c;
+	char got_data;
=20
-again:
-	val =3D 0; base =3D 10; digit =3D 0;
-	if (*cp =3D=3D '0')
-		digit =3D 1, base =3D 8, cp++;
-	if (*cp =3D=3D 'x' || *cp =3D=3D 'X')
-		base =3D 16, cp++;
-	while ((c =3D *cp) !=3D 0) {
-		if (isdigit((unsigned char)c)) {
-			if (base =3D=3D 8U && (c =3D=3D '8' || c =3D=3D '9'))
+	res =3D 0;
+	dots =3D 0;
+	for (;;) {
+		val =3D 0;
+		got_data =3D 0;
+		if (*s =3D=3D '0') {
+			s++;
+			if (*s =3D=3D 'x' || *s =3D=3D 'X') {
+				s++;
+				base =3D 16;
+			} else {
+				base =3D 8;
+				got_data =3D 1;
+			}
+		} else
+			base =3D 10;
+		while ((c =3D *s) !=3D '\0') {
+			if (isdigit(c)) {
+				if (base =3D=3D 8 && c > '7')
+					return (INADDR_NONE);
+				val =3D val * base + c - '0';
+			} else if (base =3D=3D 16 && isxdigit(c))
+				val =3D (val << 4) + c + 10 -
+				    (islower(c) ? 'a' : 'A');
+			else
+				break;
+			if (val > 0xff)
 				return (INADDR_NONE);
-			val =3D (val * base) + (c - '0');
-			cp++;
-			digit =3D 1;
-			continue;
+			s++;
+			got_data =3D 1;
 		}
-		if (base =3D=3D 16U && isxdigit((unsigned char)c)) {
-			val =3D (val << 4) +
-			      (c + 10 - (islower((unsigned char)c) ? 'a' : 'A'));
-			cp++;
-			digit =3D 1;
-			continue;
-		}
-		break;
-	}
-	if (!digit)
-		return (INADDR_NONE);
-	if (pp >=3D parts + 4 || val > 0xffU)
-		return (INADDR_NONE);
-	if (*cp =3D=3D '.') {
-		*pp++ =3D val, cp++;
-		goto again;
-	}
-	if (*cp && !isspace(*cp&0xff))
-		return (INADDR_NONE);
-	*pp++ =3D val;
-	n =3D pp - parts;
-	if (n > 4U)
-		return (INADDR_NONE);
-	for (val =3D 0, i =3D 0; i < n; i++) {
-		val <<=3D 8;
-		val |=3D parts[i] & 0xff;
+		if (!got_data)
+			return (INADDR_NONE);
+		if (dots !=3D 0)
+			res <<=3D 8;
+		res |=3D val;
+		if (c !=3D '.')
+			break;
+		if (++dots =3D=3D 4)
+			return (INADDR_NONE);
+		s++;
 	}
-	return (val);
+	return (c =3D=3D '\0' ? res : INADDR_NONE);
 }
=20
 /*
Comment 3 Andrey Simonenko 2011-01-24 12:56:25 UTC
Since all '=' were changed to '=3D' in previous email, here is the copy
of diff for the inet_network.c file.

--- inet_network.c.orig	2008-01-15 00:55:20.000000000 +0200
+++ inet_network.c	2011-01-21 15:58:17.000000000 +0200
@@ -48,57 +48,56 @@ __FBSDID("$FreeBSD: src/lib/libc/inet/in
  * network numbers.
  */
 in_addr_t
-inet_network(cp)
-	const char *cp;
+inet_network(const char *s)
 {
-	in_addr_t val, base, n;
-	char c;
-	in_addr_t parts[4], *pp = parts;
-	int i, digit;
+	u_int base, dots;
+	in_addr_t res, val;
+	u_char c;
+	char got_data;
 
-again:
-	val = 0; base = 10; digit = 0;
-	if (*cp == '0')
-		digit = 1, base = 8, cp++;
-	if (*cp == 'x' || *cp == 'X')
-		base = 16, cp++;
-	while ((c = *cp) != 0) {
-		if (isdigit((unsigned char)c)) {
-			if (base == 8U && (c == '8' || c == '9'))
+	res = 0;
+	dots = 0;
+	for (;;) {
+		val = 0;
+		got_data = 0;
+		if (*s == '0') {
+			s++;
+			if (*s == 'x' || *s == 'X') {
+				s++;
+				base = 16;
+			} else {
+				base = 8;
+				got_data = 1;
+			}
+		} else
+			base = 10;
+		while ((c = *s) != '\0') {
+			if (isdigit(c)) {
+				if (base == 8 && c > '7')
+					return (INADDR_NONE);
+				val = val * base + c - '0';
+			} else if (base == 16 && isxdigit(c))
+				val = (val << 4) + c + 10 -
+				    (islower(c) ? 'a' : 'A');
+			else
+				break;
+			if (val > 0xff)
 				return (INADDR_NONE);
-			val = (val * base) + (c - '0');
-			cp++;
-			digit = 1;
-			continue;
+			s++;
+			got_data = 1;
 		}
-		if (base == 16U && isxdigit((unsigned char)c)) {
-			val = (val << 4) +
-			      (c + 10 - (islower((unsigned char)c) ? 'a' : 'A'));
-			cp++;
-			digit = 1;
-			continue;
-		}
-		break;
-	}
-	if (!digit)
-		return (INADDR_NONE);
-	if (pp >= parts + 4 || val > 0xffU)
-		return (INADDR_NONE);
-	if (*cp == '.') {
-		*pp++ = val, cp++;
-		goto again;
-	}
-	if (*cp && !isspace(*cp&0xff))
-		return (INADDR_NONE);
-	*pp++ = val;
-	n = pp - parts;
-	if (n > 4U)
-		return (INADDR_NONE);
-	for (val = 0, i = 0; i < n; i++) {
-		val <<= 8;
-		val |= parts[i] & 0xff;
+		if (!got_data)
+			return (INADDR_NONE);
+		if (dots != 0)
+			res <<= 8;
+		res |= val;
+		if (c != '.')
+			break;
+		if (++dots == 4)
+			return (INADDR_NONE);
+		s++;
 	}
-	return (val);
+	return (c == '\0' ? res : INADDR_NONE);
 }
 
 /*
Comment 4 Andrey Simonenko 2012-10-23 09:36:04 UTC
I optimized inet_network() again.

Difference between implementation of inet_network(3) from 9.1-PRERELEASE
and my implementation.

STRING			INET_NETWORK	INET_NETWORK_NEW
"0x12"			0x00000012	0x00000012
"127.1"			0x00007f01	0x00007f01
"127.1.2.3"		0x7f010203	0x7f010203
"0x123456"		INADDR_NONE	INADDR_NONE
"0x12.0x34"		0x00001234	0x00001234
"0x12.0x345"		INADDR_NONE	INADDR_NONE
"1.2.3.4.5"		INADDR_NONE	INADDR_NONE
"1..3.4"		INADDR_NONE	INADDR_NONE
"."			INADDR_NONE	INADDR_NONE
"1."			INADDR_NONE	INADDR_NONE
".1"			INADDR_NONE	INADDR_NONE
"0x"			0x00000000	INADDR_NONE	<---
"0"			0x00000000	0x00000000
"01.02.07.077"		0x0102073f	0x0102073f
"0x1.23.045.0"		0x01172500	0x01172500
""			INADDR_NONE	INADDR_NONE
" "			INADDR_NONE	INADDR_NONE
" f"			INADDR_NONE	INADDR_NONE
"bar"			INADDR_NONE	INADDR_NONE
"1.2bar"		INADDR_NONE	INADDR_NONE
"1."			INADDR_NONE	INADDR_NONE
"=CA=C3=D5=CB=C5=CE"		INADDR_NONE	INADDR_NONE
"255.255.255.255"	INADDR_NONE	INADDR_NONE
"x"			INADDR_NONE	INADDR_NONE
"0X12"			0x00000012	0x00000012
"078"			INADDR_NONE	INADDR_NONE
"1 bar"			0x00000001	INADDR_NONE	<---
"127.0xabcd"		INADDR_NONE	INADDR_NONE
"128"			0x00000080	0x00000080
"0.1.2"			0x00000102	0x00000102
"0xff.010.23.0xa0"	0xff0817a0	0xff0817a0
"x10"			0x00000010	INADDR_NONE	<---
"X20"			0x00000020	INADDR_NONE	<---
"x10.x20"		0x00001020	INADDR_NONE	<---
"4294967297"		0x00000001	INADDR_NONE	<---
"0x10000000f"		0x0000000f	INADDR_NONE	<---
"040000000003"		0x00000003	INADDR_NONE	<---

#include <sys/types.h>
#include <sys/socket.h>

#include <netinet/in.h>
#include <arpa/inet.h>

#include <ctype.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static in_addr_t
inet_network_new(const char *s)
{
	u_int d, base, dots;
	in_addr_t addr, byte;
	u_char c;
	bool flag;

	addr =3D 0;
	dots =3D 0;
	for (;; ++s) {
		byte =3D 0;
		flag =3D false;
		if (*s =3D=3D '0') {
			++s;
			if (*s =3D=3D 'x' || *s =3D=3D 'X') {
				++s;
				base =3D 16;
			} else {
				base =3D 8;
				flag =3D true;
			}
		} else
			base =3D 10;
		for (; (c =3D *s) !=3D '\0'; ++s) {
			d =3D digittoint(c);
			if (c !=3D '0' && (d =3D=3D 0 || d >=3D base))
				break;
			byte =3D byte * base + d;
			if (byte > UINT8_MAX)
				return (INADDR_NONE);
			flag =3D true;
		}
		if (!flag)
			return (INADDR_NONE);
		addr =3D (addr << 8) | byte;
		if (c !=3D '.')
			break;
		if (++dots =3D=3D 4)
			return (INADDR_NONE);
	}
	return (c =3D=3D '\0' ? addr : INADDR_NONE);
}

int
main(void)
{
	const char *const addr_str_tbl[] =3D {
	    "0x12", "127.1", "127.1.2.3", "0x123456", "0x12.0x34",
	    "0x12.0x345", "1.2.3.4.5", "1..3.4", ".", "1.", ".1", "0x",
	    "0", "01.02.07.077", "0x1.23.045.0", "", " ", " f", "bar",
	    "1.2bar", "1.", "=CA=C3=D5=CB=C5=CE", "255.255.255.255", "x", "0X12"=
, "078",
	    "1 bar", "127.0xabcd", "128", "0.1.2", "0xff.010.23.0xa0",
	    "x10", "X20", "x10.x20", "4294967297", "0x10000000f",
	    "040000000003", NULL };
	const char *const *addr_str;
	size_t len;
	in_addr_t addr1, addr2;

	printf("STRING\t\t\tINET_NETWORK\tINET_NETWORK_NEW\n");
	for (addr_str =3D addr_str_tbl; *addr_str !=3D NULL; ++addr_str) {
		printf("\"%s\"", *addr_str);
		len =3D strlen(*addr_str) + 2;
		if (len < 8)
			printf("\t\t\t");
		else if (len < 16)
			printf("\t\t");
		else
			printf("\t");
		addr1 =3D inet_network(*addr_str);
		if (addr1 =3D=3D INADDR_NONE)
			printf("INADDR_NONE\t");
		else
			printf("0x%08x\t", addr1);
		addr2 =3D inet_network_new(*addr_str);
		if (addr2 =3D=3D INADDR_NONE)
			printf("INADDR_NONE");
		else
			printf("0x%08x", addr2);
		if (addr1 !=3D addr2)
			printf("\t<---");
		printf("\n");
	}
	return (0);
}
Comment 5 Eitan Adler freebsd_committer freebsd_triage 2017-12-31 08:00:45 UTC
For bugs matching the following criteria:

Status: In Progress Changed: (is less than) 2014-06-01

Reset to default assignee and clear in-progress tags.

Mail being skipped