Project import generated by Copybara.

NOKEYCHECK=True
GitOrigin-RevId: da1f80483036e2b4a67895500268e5d994565c80
diff --git a/nspr.patches/nspr-50.patch b/nspr.patches/nspr-50.patch
new file mode 100644
index 0000000..164cce3
--- /dev/null
+++ b/nspr.patches/nspr-50.patch
@@ -0,0 +1,25 @@
+diff -aruN nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/unix.c nspr-4.8.6.N/mozilla/nsprpub/pr/src/md/unix/unix.c
+--- nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/unix.c	2010-02-09 19:03:35.000000000 -0800
++++ nspr-4.8.6.N/mozilla/nsprpub/pr/src/md/unix/unix.c	2011-04-15 11:10:27.000000000 -0700
+@@ -3026,12 +3026,21 @@
+ 
+ PRIntervalTime _PR_UNIX_GetInterval()
+ {
++#if defined(XP_MACOSX)
+     struct timeval time;
+     PRIntervalTime ticks;
+ 
+     (void)GETTIMEOFDAY(&time);  /* fallicy of course */
+     ticks = (PRUint32)time.tv_sec * PR_MSEC_PER_SEC;  /* that's in milliseconds */
+     ticks += (PRUint32)time.tv_usec / PR_USEC_PER_MSEC;  /* so's that */
++#else
++    struct timespec time;
++    PRIntervalTime ticks;
++
++    (void)clock_gettime(CLOCK_MONOTONIC, &time);
++    ticks = (PRUint32)time.tv_sec * PR_MSEC_PER_SEC;  /* that's in milliseconds */
++    ticks += (PRUint32)((PRUint64)time.tv_nsec / PR_NSEC_PER_MSEC);  /* so's that */
++#endif
+     return ticks;
+ }  /* _PR_SUNOS_GetInterval */
+ 
diff --git a/nspr.patches/nspr-51.patch b/nspr.patches/nspr-51.patch
new file mode 100644
index 0000000..14b5503
--- /dev/null
+++ b/nspr.patches/nspr-51.patch
@@ -0,0 +1,233 @@
+--- nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prtime.c	2010-03-30 12:15:26.000000000 -0700
++++ nspr-4.8.6.N/mozilla/nsprpub/pr/src/misc/prtime.c	2013-10-21 13:55:53.000000000 -0700
+@@ -102,6 +102,7 @@
+ static void        ComputeGMT(PRTime time, PRExplodedTime *gmt);
+ static int         IsLeapYear(PRInt16 year);
+ static void        ApplySecOffset(PRExplodedTime *time, PRInt32 secOffset);
++static void        AdjustDSTGMTOffsets(PRTime time, PRExplodedTime *exploded);
+ 
+ /*
+  *------------------------------------------------------------------------
+@@ -244,6 +245,7 @@
+     exploded->tm_params = params(exploded);
+     ApplySecOffset(exploded, exploded->tm_params.tp_gmt_offset
+             + exploded->tm_params.tp_dst_offset);
++    AdjustDSTGMTOffsets(usecs, exploded);
+ }
+ 
+ 
+@@ -581,11 +583,68 @@
+ 
+ #endif  /* definition of MT_safe_localtime() */
+ 
++static PRBool ComputeLocalTime(time_t local, struct tm *ptm)
++{
++#ifdef HAVE_LOCALTIME_R
++    return localtime_r(&local, ptm);
++
++#elif HAVE_LOCALTIME_MONITOR
++
++    if (MT_safe_localtime(&local, ptm) != NULL)
++        return PR_TRUE;
++    else
++        return PR_FALSE;
++#else
++
++    #error no ComputeLocalTime()
++
++#endif /* definition of ComputeLocalTime() */
++}
++
++#ifndef HAVE_GMTIME_R
++
++#define HAVE_GMT_MONITOR 1  /* We use 'monitorgmt' to serialize our calls
++                             * to gmtime(). */
++
++static PRLock *monitorgmt = NULL;
++#endif
++
++static PRBool ComputeUTCTime(time_t t, struct tm *ptm)
++{
++#ifdef HAVE_GMTIME_R
++    return gmtime_r(&t, ptm);
++#else
++    PRBool retval = PR_TRUE;
++    struct tm *otm = NULL;
++    int needLock = PR_Initialized();  /* We need to use a lock to protect
++                                       * against NSPR threads only when the
++                                       * NSPR thread system is activated. */
++    if (needLock) PR_Lock(monitorgmt);
++
++    otm = gmtime(&t);
++
++    if (!otm)
++        retval = PR_FALSE;
++    else
++    {
++        *ptm = *otm;
++        retval = PR_TRUE;
++    }
++
++    if (needLock) PR_Unlock(monitorgmt);
++
++    return retval;
++#endif /* definition of ComputeUTCTime() */
++}
++
+ void _PR_InitTime(void)
+ {
+ #ifdef HAVE_LOCALTIME_MONITOR
+     monitor = PR_NewLock();
+ #endif
++#ifdef HAVE_GMT_MONITOR
++    monitorgmt = PR_NewLock();
++#endif
+ #ifdef WINCE
+     _MD_InitTime();
+ #endif
+@@ -599,11 +658,118 @@
+         monitor = NULL;
+     }
+ #endif
++#ifdef HAVE_GMT_MONITOR
++    if (monitorgmt) {
++        PR_DestroyLock(monitorgmt);
++        monitorgmt = NULL;
++    }
++#endif
+ #ifdef WINCE
+     _MD_CleanupTime();
+ #endif
+ }
+ 
++/*
++ * from https://mxr.mozilla.org/mozilla-central/source/js/src/vm/DateTime.cpp?rev=699228670afb
++ * but slightly adjusted as the modzilla has an issue during the hours close to the dst-std change
++ * Compute the offset in seconds from the current UTC time to the current local
++ * time
++ *
++ * Examples:
++ *
++ * Suppose we are in California, USA on January 1, 2013 at 04:00 PST (UTC-8, no
++ * DST in effect), corresponding to 12:00 UTC.  This function would then return
++ * -8 * SecondsPerHour, or -28800.
++ *
++ * Or suppose we are in Berlin, Germany on July 1, 2013 at 17:00 CEST (UTC+2,
++ * DST in effect), corresponding to 15:00 UTC.  This function would then return
++ * +2 * SecondsPerHour, or +7200.
++ */
++static PRInt32
++UTCToLocalTimeOffsetSeconds(time_t time)
++{
++    PRInt32 SecondsPerDay = 86400;
++    PRInt32 SecondsPerHour = 3600;
++    PRInt32 SecondsPerMinute = 60;
++    struct tm local;
++    struct tm utc;
++
++    memset(&local, 0, sizeof(local));
++    memset(&utc, 0, sizeof(utc));
++
++
++#if defined(XP_WIN)
++    // Windows doesn't follow POSIX: updates to the TZ environment variable are
++    // not reflected immediately on that platform as they are on other systems
++    // without this call.
++    _tzset();
++#endif
++
++    // Break down the current time into its components.
++    if (!ComputeLocalTime(time, &local))
++        return 0;
++
++    // Break down the local time into UTC-based components.
++    memset(&utc, 0, sizeof(utc));
++    if (!ComputeUTCTime(time, &utc))
++        return 0;
++
++    // Finally, compare the seconds-based components of the local
++    // representation and the UTC representation to determine the actual
++    // difference.
++    PRInt32 utc_secs = utc.tm_hour * SecondsPerHour + utc.tm_min * SecondsPerMinute;
++    PRInt32 local_secs = local.tm_hour * SecondsPerHour + local.tm_min * SecondsPerMinute;
++
++    // Same-day?  Just subtract the seconds counts.
++    if (utc.tm_mday == local.tm_mday)
++        return local_secs - utc_secs;
++
++    // If we have more UTC seconds, move local seconds into the UTC seconds'
++    // frame of reference and then subtract.
++    if (utc_secs > local_secs)
++        return (SecondsPerDay + local_secs) - utc_secs;
++
++    // Otherwise we have more local seconds, so move the UTC seconds into the
++    // local seconds' frame of reference and then subtract.
++    return local_secs - (utc_secs + SecondsPerDay);
++}
++
++static void
++AdjustDSTGMTOffsets(PRTime time, PRExplodedTime *exploded)
++{
++    PRInt64 sec64;
++    PRInt64 usecPerSec;
++    PRInt32 overallOffsetFromUTC;
++    PRInt32 dstoffset = 3600;
++    struct tm localTime;
++    time_t timetsecs;
++
++    LL_I2L(usecPerSec, 1000000L);
++    LL_DIV(sec64, time, usecPerSec);
++
++    timetsecs = sec64;
++
++    /*
++     *  overall_offset = gmt_offset + dst_offset
++     */
++    overallOffsetFromUTC = UTCToLocalTimeOffsetSeconds(timetsecs);
++
++    /*
++     *  used the passed time to calculate the right offsets based on
++     *  linux call to localtime
++     */
++    (void) MT_safe_localtime(&timetsecs, &localTime);
++
++    if (localTime.tm_isdst <= 0) {
++        /* DST is not in effect */
++        exploded->tm_params.tp_gmt_offset = overallOffsetFromUTC;
++        exploded->tm_params.tp_dst_offset = 0;
++    } else {
++        exploded->tm_params.tp_gmt_offset = overallOffsetFromUTC - dstoffset;
++        exploded->tm_params.tp_dst_offset = dstoffset;
++    }
++}
++
+ #if defined(XP_UNIX) || defined(XP_PC) || defined(XP_BEOS)
+ 
+ PR_IMPLEMENT(PRTimeParameters)
+@@ -642,7 +808,7 @@
+ 
+     /* GMT is 00:00:00, 2nd of Jan. */
+ 
+-    offset2Jan1970 = (PRInt32)localTime.tm_sec 
++    offset2Jan1970 = (PRInt32)localTime.tm_sec
+             + 60L * (PRInt32)localTime.tm_min
+             + 3600L * (PRInt32)localTime.tm_hour
+             + 86400L * (PRInt32)((PRInt32)localTime.tm_mday - 2L);
+@@ -696,7 +862,7 @@
+     }
+ 
+     /*
+-     * dayOffset is the offset between local time and GMT in 
++     * dayOffset is the offset between local time and GMT in
+      * the day component, which can only be -1, 0, or 1.  We
+      * use the day of the week to compute dayOffset.
+      */
+@@ -745,7 +911,7 @@
+             retVal.tp_dst_offset = 3600;
+         }
+     }
+-    
++
+     return retVal;
+ }
+ 
diff --git a/nspr.patches/nspr-52.patch b/nspr.patches/nspr-52.patch
new file mode 100644
index 0000000..294a929
--- /dev/null
+++ b/nspr.patches/nspr-52.patch
@@ -0,0 +1,67 @@
+diff -aruN nspr-4.8.6/mozilla/nsprpub/pr/include/prtime.h nspr-4.8.6.N/mozilla/nsprpub/pr/include/prtime.h
+--- nspr-4.8.6/mozilla/nsprpub/pr/include/prtime.h	2009-03-03 08:17:48.000000000 -0800
++++ nspr-4.8.6.N/mozilla/nsprpub/pr/include/prtime.h	2015-04-29 16:32:24.000000000 -0700
+@@ -206,7 +206,10 @@
+  *     should treat them as "read-only".
+  */
+ 
+-NSPR_API(void) PR_NormalizeTime(
++NSPR_API(PRTime) PR_NormalizeTime(
++    PRExplodedTime *exploded, PRTimeParamFn params);
++
++NSPR_API(void) PR_NormalizeTime_NoDSTAdjust(
+     PRExplodedTime *exploded, PRTimeParamFn params);
+ 
+ /**********************************************************************/
+diff -aruN nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prtime.c nspr-4.8.6.N/mozilla/nsprpub/pr/src/misc/prtime.c
+--- nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prtime.c	2015-04-29 16:33:57.000000000 -0700
++++ nspr-4.8.6.N/mozilla/nsprpub/pr/src/misc/prtime.c	2015-04-29 16:33:10.000000000 -0700
+@@ -272,7 +272,7 @@
+ 
+     /* Normalize first.  Do this on our copy */
+     copy = *exploded;
+-    PR_NormalizeTime(&copy, PR_GMTParameters);
++    PR_NormalizeTime_NoDSTAdjust(&copy, PR_GMTParameters);
+ 
+     numDays = DAYS_BETWEEN_YEARS(1970, copy.tm_year);
+     
+@@ -387,9 +387,29 @@
+     }
+ }
+ 
+-PR_IMPLEMENT(void)
++NSPR_API(PRTime)
+ PR_NormalizeTime(PRExplodedTime *time, PRTimeParamFn params)
+ {
++    PRTime resolvedtime;
++    PR_NormalizeTime_NoDSTAdjust(time, PR_LocalTimeParameters);
++
++    // Resolve DST shifts explicitly. Note that this will also update *time
++    // with the corrected time.
++    resolvedtime = PR_ImplodeTime(time);
++    PR_ExplodeTime(resolvedtime, params, time);
++
++    // Return the DST-resolved PRTime.
++    return resolvedtime;
++}
++
++// This function normalizes time, but does not always resolve Daylight Savings
++// Time correctly (see SAPPHIRE-10133 for an example). It is the original
++// built-in PR_NormalizeTime function in NSPR, but should not be used outside
++// of the functions in this file - users should continue to utilize the newer
++// PR_NormalizeTime function below (see SAPPHIRE-10152).
++PR_IMPLEMENT(void)
++PR_NormalizeTime_NoDSTAdjust(PRExplodedTime *time, PRTimeParamFn params)
++{
+     int daysInMonth;
+     PRInt32 numDays;
+ 
+@@ -1723,7 +1743,7 @@
+    * Mainly to compute wday and yday, but normalized time is also required
+    * by the check below that works around a Visual C++ 2005 mktime problem.
+    */
+-  PR_NormalizeTime(result, PR_GMTParameters);
++  PR_NormalizeTime_NoDSTAdjust(result, PR_GMTParameters);
+   /* The remaining work is to set the gmt and dst offsets in tm_params. */
+ 
+   if (zone == TT_UNKNOWN && default_to_gmt)
diff --git a/nspr.patches/nspr-53.patch b/nspr.patches/nspr-53.patch
new file mode 100644
index 0000000..2eeee82
--- /dev/null
+++ b/nspr.patches/nspr-53.patch
@@ -0,0 +1,44 @@
+diff -aruN nspr-4.8.6/mozilla/nsprpub/pr/include/prprf.h nspr-4.8.6.N/mozilla/nsprpub/pr/include/prprf.h
+--- nspr-4.8.6/mozilla/nsprpub/pr/include/prprf.h	2004-04-25 08:00:47.000000000 -0700
++++ nspr-4.8.6.N/mozilla/nsprpub/pr/include/prprf.h	2015-05-08 11:15:40.200961412 -0700
+@@ -48,6 +48,8 @@
+ **	%hd, %hu, %hx, %hX, %ho - 16-bit versions of above
+ **	%ld, %lu, %lx, %lX, %lo - 32-bit versions of above
+ **	%lld, %llu, %llx, %llX, %llo - 64 bit versions of above
++**	%td, %tu, %tx, %tX, %to - PRPtrdiff versions of the above (deals with machine dependent PRPtrdiff size)
++**	%zd, %zu, %zx, %zX, %zo - PRSize versions of above (deals with machine dependent PRSize size)
+ **	%s - string
+ **	%c - character
+ **	%p - pointer (deals with machine dependent pointer size)
+diff -aruN nspr-4.8.6/mozilla/nsprpub/pr/src/io/prprf.c nspr-4.8.6.N/mozilla/nsprpub/pr/src/io/prprf.c
+--- nspr-4.8.6/mozilla/nsprpub/pr/src/io/prprf.c	2008-05-31 08:10:17.000000000 -0700
++++ nspr-4.8.6.N/mozilla/nsprpub/pr/src/io/prprf.c	2015-05-08 11:12:46.305410769 -0700
+@@ -820,6 +820,28 @@
+ 		type = TYPE_INT64;
+ 		c = *fmt++;
+ 	    }
++	} else if (c == 't') {
++		if (sizeof(PRPtrdiff) == sizeof(PRInt32)) {
++		    type = TYPE_UINT32;
++		} else if (sizeof(PRPtrdiff) == sizeof(PRInt64)) {
++		    type = TYPE_UINT64;
++		} else if (sizeof(PRPtrdiff) == sizeof(PRIntn)) {
++		    type = TYPE_UINTN;
++		} else {
++		    PR_ASSERT(0);
++		}
++		c = *fmt++;
++	} else if (c == 'z') {
++		if (sizeof(PRSize) == sizeof(PRInt32)) {
++		    type = TYPE_UINT32;
++		} else if (sizeof(PRSize) == sizeof(PRInt64)) {
++		    type = TYPE_UINT64;
++		} else if (sizeof(PRSize) == sizeof(PRIntn)) {
++		    type = TYPE_UINTN;
++		} else {
++		    PR_ASSERT(0);
++		}
++		c = *fmt++;
+ 	}
+ 
+ 	/* format */
diff --git a/nspr.patches/nspr-54.patch b/nspr.patches/nspr-54.patch
new file mode 100644
index 0000000..8a65201
--- /dev/null
+++ b/nspr.patches/nspr-54.patch
@@ -0,0 +1,26 @@
+diff -aruN nspr-4.8.6/mozilla/nsprpub/pr/include/prtime.h nspr-4.8.6.N/mozilla/nsprpub/pr/include/prtime.h
+--- nspr-4.8.6/mozilla/nsprpub/pr/include/prtime.h	2016-01-21 12:46:01.000000000 -0800
++++ nspr-4.8.6.N/mozilla/nsprpub/pr/include/prtime.h	2016-01-21 12:44:49.000000000 -0800
+@@ -50,6 +50,9 @@
+ 
+ #include "prlong.h"
+ 
++#define HAVE_POINTER_LOCALTIME_R 1
++#define HAVE_LOCALTIME_R 1
++
+ PR_BEGIN_EXTERN_C
+ 
+ /**********************************************************************/
+diff -aruN nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prtime.c nspr-4.8.6.N/mozilla/nsprpub/pr/src/misc/prtime.c
+--- nspr-4.8.6/mozilla/nsprpub/pr/src/misc/prtime.c	2016-01-21 12:46:01.000000000 -0800
++++ nspr-4.8.6.N/mozilla/nsprpub/pr/src/misc/prtime.c	2016-01-21 12:45:04.000000000 -0800
+@@ -823,6 +823,9 @@
+      *    since Jan. 2, 1970.
+      */
+ 
++    /* Run tzset() to guarantee that we are using up-to-date time parameters. */
++    tzset();
++
+     secs = 86400L;
+     (void) MT_safe_localtime(&secs, &localTime);
+ 
diff --git a/nspr.patches/nspr-55.patch b/nspr.patches/nspr-55.patch
new file mode 100644
index 0000000..58b2981
--- /dev/null
+++ b/nspr.patches/nspr-55.patch
@@ -0,0 +1,22 @@
+--- nspr-4.8.6/mozilla/nsprpub/configure.in
++++ nspr-4.8.6.N/mozilla/nsprpub/configure.in
+@@ -1139,7 +1139,7 @@
+             ;;
+     esac
+     DSO_CFLAGS=-fPIC
+-    DSO_LDOPTS='-dynamiclib -compatibility_version 1 -current_version 1 -all_load -install_name @executable_path/$@ -headerpad_max_install_names'
++    DSO_LDOPTS='-dynamiclib -compatibility_version 1 -current_version 1 -all_load -install_name $(libdir)/$@ -headerpad_max_install_names'
+     _OPTIMIZE_FLAGS=-O2
+     MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@'
+     STRIP="$STRIP -x -S"
+--- nspr-4.8.6/mozilla/nsprpub/configure
++++ nspr-4.8.6.N/mozilla/nsprpub/configure
+@@ -3535,7 +3535,7 @@
+             ;;
+     esac
+     DSO_CFLAGS=-fPIC
+-    DSO_LDOPTS='-dynamiclib -compatibility_version 1 -current_version 1 -all_load -install_name @executable_path/$@ -headerpad_max_install_names'
++    DSO_LDOPTS='-dynamiclib -compatibility_version 1 -current_version 1 -all_load -install_name $(libdir)/$@ -headerpad_max_install_names'
+     _OPTIMIZE_FLAGS=-O2
+     MKSHLIB='$(CC) $(DSO_LDOPTS) -o $@'
+     STRIP="$STRIP -x -S"
diff --git a/nspr.patches/nspr-56.patch b/nspr.patches/nspr-56.patch
new file mode 100644
index 0000000..0e6a857
--- /dev/null
+++ b/nspr.patches/nspr-56.patch
@@ -0,0 +1,38 @@
+diff -aruN nspr-4.8.6/mozilla/nsprpub/pr/include/prlock.h nspr-4.8.6.N/mozilla/nsprpub/pr/include/prlock.h
+--- nspr-4.8.6/mozilla/nsprpub/pr/include/prlock.h	2009-03-18 14:29:29.000000000 -0700
++++ nspr-4.8.6.N/mozilla/nsprpub/pr/include/prlock.h	2016-08-26 08:21:19.494206783 -0700
+@@ -117,6 +117,18 @@
+ NSPR_API(PRStatus) PR_Unlock(PRLock *lock);
+ 
+ /***********************************************************************
++** FUNCTION:    PR_IsLocked
++** DESCRIPTION:
++**  Determine if a lock is locked.
++** INPUTS:      PRLock *lock
++**              Lock to determine.
++** OUTPUTS:     void
++** RETURN:      PRBool
++**              Returns PR_TRUE if lock is locked, else PR_FALSE.
++***********************************************************************/
++NSPR_API(PRBool) PR_IsLocked(PRLock *lock);
++
++/***********************************************************************
+ ** MACRO:    PR_ASSERT_CURRENT_THREAD_OWNS_LOCK
+ ** DESCRIPTION:
+ **  If the current thread owns |lock|, this assertion is guaranteed to
+diff -aruN nspr-4.8.6/mozilla/nsprpub/pr/src/pthreads/ptsynch.c nspr-4.8.6.N/mozilla/nsprpub/pr/src/pthreads/ptsynch.c
+--- nspr-4.8.6/mozilla/nsprpub/pr/src/pthreads/ptsynch.c	2010-07-11 10:14:39.000000000 -0700
++++ nspr-4.8.6.N/mozilla/nsprpub/pr/src/pthreads/ptsynch.c	2016-08-26 08:12:02.026296557 -0700
+@@ -245,6 +245,12 @@
+     return PR_SUCCESS;
+ }  /* PR_Unlock */
+ 
++PR_IMPLEMENT(PRBool) PR_IsLocked(PRLock *lock)
++{
++    PR_ASSERT(lock != NULL);
++    return lock->locked;
++}
++
+ PR_IMPLEMENT(void) PR_AssertCurrentThreadOwnsLock(PRLock *lock)
+ {
+     /* Nb: the order of the |locked| and |owner==me| checks is not critical 
diff --git a/nspr.patches/nspr-57.patch b/nspr.patches/nspr-57.patch
new file mode 100644
index 0000000..3f38aad
--- /dev/null
+++ b/nspr.patches/nspr-57.patch
@@ -0,0 +1,15 @@
+diff -Naur a/mozilla/nsprpub/pr/src/io/prprf.c b/mozilla/nsprpub/pr/src/io/prprf.c
+--- a/mozilla/nsprpub/pr/src/io/prprf.c	2016-12-15 14:35:07.756707522 -0800
++++ b/mozilla/nsprpub/pr/src/io/prprf.c	2016-12-15 14:35:59.509256020 -0800
+@@ -814,7 +814,11 @@
+ 	    type = TYPE_INT64;
+ 	    c = *fmt++;
+ 	} else if (c == 'l') {
++#if PR_BYTES_PER_LONG == 8
++	    type = TYPE_INT64;
++#else
+ 	    type = TYPE_INT32;
++#endif
+ 	    c = *fmt++;
+ 	    if (c == 'l') {
+ 		type = TYPE_INT64;
diff --git a/nspr.patches/nspr-58.patch b/nspr.patches/nspr-58.patch
new file mode 100644
index 0000000..778f007
--- /dev/null
+++ b/nspr.patches/nspr-58.patch
@@ -0,0 +1,27 @@
+diff -Naur a/mozilla/nsprpub/pr/src/pthreads/ptio.c b/mozilla/nsprpub/pr/src/pthreads/ptio.c
+--- a/mozilla/nsprpub/pr/src/pthreads/ptio.c	2017-07-25 16:58:21.471397566 -0700
++++ b/mozilla/nsprpub/pr/src/pthreads/ptio.c 	2017-07-25 16:58:07.367175478 -0700
+@@ -3411,6 +3411,12 @@
+     return fd;
+ }  /* PR_AllocFileDesc */
+ 
++PR_IMPLEMENT(void) PR_FreeFileDesc(PRFileDesc *fd)
++{
++    PR_ASSERT(fd);
++    _PR_Putfd(fd);
++}
++
+ #if !defined(_PR_INET6) || defined(_PR_INET6_PROBE)
+ PR_EXTERN(PRStatus) _pr_push_ipv6toipv4_layer(PRFileDesc *fd);
+ #if defined(_PR_INET6_PROBE)
+diff -Naur a/mozilla/nsprpub/pr/src/nspr.def b/mozilla/nsprpub/pr/src/nspr.def
+--- a/mozilla/nsprpub/pr/src/nspr.def	2009-03-18 14:29:31.000000000 -0700
++++ b/mozilla/nsprpub/pr/src/nspr.def 	2017-07-25 17:06:39.035233443 -0700
+@@ -167,6 +167,7 @@
+ 		PR_FindNextTraceRname;
+ 		PR_FormatTimeUSEnglish;
+ 		PR_Free;
++		PR_FreeFileDesc;
+ 		PR_FreeLibraryName;
+ 		PR_GMTParameters;
+ 		PR_GetConnectStatus;
diff --git a/nspr.patches/nspr-59.patch b/nspr.patches/nspr-59.patch
new file mode 100644
index 0000000..0269b0a
--- /dev/null
+++ b/nspr.patches/nspr-59.patch
@@ -0,0 +1,10 @@
+Index: nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/uxproces.c
+===================================================================
+--- nspr-4.8.6.orig/mozilla/nsprpub/pr/src/md/unix/uxproces.c
++++ nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/uxproces.c
+@@ -1,4 +1,4 @@
+-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+ /* ***** BEGIN LICENSE BLOCK *****
+  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+  *
diff --git a/nspr.patches/nspr-60.patch b/nspr.patches/nspr-60.patch
new file mode 100644
index 0000000..42aafaa
--- /dev/null
+++ b/nspr.patches/nspr-60.patch
@@ -0,0 +1,126 @@
+Index: nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/uxproces.c
+===================================================================
+--- nspr-4.8.6.orig/mozilla/nsprpub/pr/src/md/unix/uxproces.c
++++ nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/uxproces.c
+@@ -459,6 +459,29 @@ _MD_CreateUnixProcess(
+ #define PID_HASH_MASK ((pid_t) (NBUCKETS - 1))
+ 
+ static pr_PidRecord *
++CreatePidRecord(void)
++{
++    pr_PidRecord *pRec;
++    pRec = PR_NEWZAP(pr_PidRecord);
++    pRec->reapedCV = PR_NewCondVar(pr_wp.ml);
++    if (NULL == pRec->reapedCV) {
++        PR_DELETE(pRec);
++        pRec = NULL;
++    }
++    return pRec;
++}
++
++static void
++DeletePidRecord(pr_PidRecord *pRec)
++{
++    if (pRec->reapedCV) {
++        PR_DestroyCondVar(pRec->reapedCV);
++        pRec->reapedCV = NULL;
++    }
++    PR_DELETE(pRec);
++}
++
++static pr_PidRecord *
+ FindPidTable(pid_t pid)
+ {
+     pr_PidRecord *pRec;
+@@ -533,18 +556,17 @@ ProcessReapedChildInternal(pid_t pid, in
+ 
+     pRec = FindPidTable(pid);
+     if (NULL == pRec) {
+-        pRec = PR_NEW(pr_PidRecord);
++        pRec = CreatePidRecord();
++        PR_ASSERT(pRec);
+         pRec->pid = pid;
+         pRec->state = _PR_PID_REAPED;
+         pRec->exitStatus = ExtractExitStatus(status);
+-        pRec->reapedCV = NULL;
+         InsertPidTable(pRec);
+     } else {
+         PR_ASSERT(pRec->state != _PR_PID_REAPED);
+         if (_PR_PID_DETACHED == pRec->state) {
+-            PR_ASSERT(NULL == pRec->reapedCV);
+             DeletePidTable(pRec);
+-            PR_DELETE(pRec);
++            DeletePidRecord(pRec);
+         } else {
+             PR_ASSERT(_PR_PID_WAITING == pRec->state);
+             PR_ASSERT(NULL != pRec->reapedCV);
+@@ -793,7 +815,7 @@ PRStatus _MD_DetachUnixProcess(PRProcess
+     PR_Lock(pr_wp.ml);
+     pRec = FindPidTable(process->md.pid);
+     if (NULL == pRec) {
+-	pRec = PR_NEW(pr_PidRecord);
++       pRec = CreatePidRecord();
+ 	if (NULL == pRec) {
+ 	    PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+ 	    retVal = PR_FAILURE;
+@@ -801,7 +823,6 @@ PRStatus _MD_DetachUnixProcess(PRProcess
+ 	}
+ 	pRec->pid = process->md.pid;
+ 	pRec->state = _PR_PID_DETACHED;
+-	pRec->reapedCV = NULL;
+ 	InsertPidTable(pRec);
+     } else {
+ 	PR_ASSERT(_PR_PID_REAPED == pRec->state);
+@@ -809,9 +830,8 @@ PRStatus _MD_DetachUnixProcess(PRProcess
+ 	    PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+ 	    retVal = PR_FAILURE;
+ 	} else {
+-	    DeletePidTable(pRec);
+-	    PR_ASSERT(NULL == pRec->reapedCV);
+-	    PR_DELETE(pRec);
++        DeletePidTable(pRec);
++        DeletePidRecord(pRec);
+ 	}
+     }
+     PR_DELETE(process);
+@@ -832,7 +852,7 @@ PRStatus _MD_WaitUnixProcess(
+     PR_Lock(pr_wp.ml);
+     pRec = FindPidTable(process->md.pid);
+     if (NULL == pRec) {
+-	pRec = PR_NEW(pr_PidRecord);
++	pRec = CreatePidRecord();
+ 	if (NULL == pRec) {
+ 	    PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+ 	    retVal = PR_FAILURE;
+@@ -840,12 +860,6 @@ PRStatus _MD_WaitUnixProcess(
+ 	}
+ 	pRec->pid = process->md.pid;
+ 	pRec->state = _PR_PID_WAITING;
+-	pRec->reapedCV = PR_NewCondVar(pr_wp.ml);
+-	if (NULL == pRec->reapedCV) {
+-	    PR_DELETE(pRec);
+-	    retVal = PR_FAILURE;
+-	    goto done;
+-	}
+ 	InsertPidTable(pRec);
+ 	while (!interrupted && _PR_PID_REAPED != pRec->state) {
+ 	    if (PR_WaitCondVar(pRec->reapedCV,
+@@ -863,16 +877,14 @@ PRStatus _MD_WaitUnixProcess(
+ 	    retVal = PR_FAILURE;
+ 	}
+ 	DeletePidTable(pRec);
+-	PR_DestroyCondVar(pRec->reapedCV);
+-	PR_DELETE(pRec);
++	DeletePidRecord(pRec);
+     } else {
+ 	PR_ASSERT(_PR_PID_REAPED == pRec->state);
+-	PR_ASSERT(NULL == pRec->reapedCV);
+ 	DeletePidTable(pRec);
+         if (exitCode) {
+             *exitCode = pRec->exitStatus;
+         }
+-	PR_DELETE(pRec);
++	DeletePidRecord(pRec);
+     }
+     PR_DELETE(process);
+ 
diff --git a/nspr.patches/nspr-61.patch b/nspr.patches/nspr-61.patch
new file mode 100644
index 0000000..fa05fbf
--- /dev/null
+++ b/nspr.patches/nspr-61.patch
@@ -0,0 +1,24 @@
+Index: nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/uxproces.c
+===================================================================
+--- nspr-4.8.6.orig/mozilla/nsprpub/pr/src/md/unix/uxproces.c
++++ nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/uxproces.c
+@@ -636,7 +636,7 @@ static void WaitPidDaemonThread(void *un
+     PRPollDesc pd;
+     PRFileDesc *fd;
+     int rv;
+-    char buf[128];
++    char ctmp;
+     pid_t pid;
+     int status;
+ #ifdef _PR_SHARE_CLONES
+@@ -664,8 +664,8 @@ static void WaitPidDaemonThread(void *un
+ #endif
+ 	    
+         do {
+-            rv = read(pr_wp.pipefd[0], buf, sizeof(buf));
+-        } while (sizeof(buf) == rv || (-1 == rv && EINTR == errno));
++            rv = read(pr_wp.pipefd[0], &ctmp, sizeof(ctmp));
++        } while (-1 == rv && EINTR == errno);
+ 
+ #ifdef _PR_SHARE_CLONES
+ 	PR_Unlock(pr_wp.ml);
diff --git a/nspr.patches/nspr-62.patch b/nspr.patches/nspr-62.patch
new file mode 100644
index 0000000..47bc1a4
--- /dev/null
+++ b/nspr.patches/nspr-62.patch
@@ -0,0 +1,217 @@
+Index: nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/uxproces.c
+===================================================================
+--- nspr-4.8.6.orig/mozilla/nsprpub/pr/src/md/unix/uxproces.c
++++ nspr-4.8.6/mozilla/nsprpub/pr/src/md/unix/uxproces.c
+@@ -60,6 +60,10 @@ PR_IMPORT_DATA(char **) environ;
+ #define SA_RESTART 0
+ #endif
+ 
++#ifndef ARRAY_SIZE
++#define ARRAY_SIZE(ra) (sizeof(ra)/sizeof((ra)[0]))
++#endif
++
+ /*
+  **********************************************************************
+  *
+@@ -457,6 +461,9 @@ _MD_CreateUnixProcess(
+ #define NBUCKETS_LOG2 6
+ #define NBUCKETS (1 << NBUCKETS_LOG2)
+ #define PID_HASH_MASK ((pid_t) (NBUCKETS - 1))
++#define BITS_PER_CHAR 8
++#define MAX_PIDS 65535
++#define MAX_ENTRIES_PER_BUCKET (MAX_PIDS / NBUCKETS)
+ 
+ static pr_PidRecord *
+ CreatePidRecord(void)
+@@ -631,14 +638,90 @@ static void WaitPidDaemonThread(void *un
+ 
+ #else /* _PR_NATIVE_THREADS */
+ 
++// only accessed from WaitPidDaemonThread()
++static pid_t pr_wp_pids[MAX_ENTRIES_PER_BUCKET];
++
++static void WaitForPidsInArray(unsigned count)
++{
++    unsigned n;
++    pid_t pid;
++    int status;
++
++    for (n = 0; n < count; ++n) {
++	do {
++	    pid = waitpid(pr_wp_pids[n], &status, WNOHANG);
++	} while ((pid_t) -1 == pid && EINTR == errno);
++
++	if (pid == 0) /* still running */
++	    continue;
++
++	PR_ASSERT((pid_t) -1 != pid);
++
++	PR_Lock(pr_wp.ml);
++	ProcessReapedChildInternal(pid, status);
++	PR_Unlock(pr_wp.ml);
++    }
++}
++
++static void WaitForPidsInBucket(unsigned bucketIndex)
++{
++    pr_PidRecord *pRec = NULL;
++    unsigned count;
++    unsigned maxIteratorInvalidation = 2;
++
++    while (1)
++    {
++	count = 0;
++
++	PR_Lock(pr_wp.ml);
++
++	if (NULL == pRec) {
++	    pRec = pr_wp.pidTable[bucketIndex];
++	} else {
++	    // while unlocked, pRec could have been deleted.
++	    pr_PidRecord *pCur = pr_wp.pidTable[bucketIndex];
++	    while ((NULL != pCur) && (pCur != pRec)) {
++		pCur = pCur->next;
++	    }
++
++	    if (NULL == pCur) {
++		if (maxIteratorInvalidation > 0) {
++		    --maxIteratorInvalidation;
++		    pRec = pr_wp.pidTable[bucketIndex];
++		} else {
++		    pRec = NULL;
++		}
++	    }
++	    // else pRec was found and is still valid
++	}
++
++	while ((NULL != pRec) && (count < ARRAY_SIZE(pr_wp_pids))) {
++	    if (pRec->pid > 0 && (_PR_PID_REAPED != pRec->state)) {
++		pr_wp_pids[count] = pRec->pid;
++		++count;
++	    }
++	    pRec = pRec->next;
++	}
++
++	PR_Unlock(pr_wp.ml);
++
++	if (count == 0)
++	    break;
++
++	WaitForPidsInArray(count);
++
++	if (NULL == pRec)
++	    break;
++    }
++}
++
+ static void WaitPidDaemonThread(void *unused)
+ {
+     PRPollDesc pd;
+     PRFileDesc *fd;
+     int rv;
+     char ctmp;
+-    pid_t pid;
+-    int status;
++    unsigned bucket;
+ #ifdef _PR_SHARE_CLONES
+     struct pr_CreateProcOp *op;
+ #endif
+@@ -677,6 +760,18 @@ static void WaitPidDaemonThread(void *un
+ 		op->oserror = PR_GetOSError();
+ 	    }
+ 	    PR_Lock(pr_wp.ml);
++	    if (op->process) {
++		pr_PidRecord *pRec = FindPidTable(op->process->md.pid);
++		// If someone forgets to detach or wait for their process,
++		// the stale entry hangs around until the OS re-uses the PID
++		PR_ASSERT(NULL == pRec);
++		pRec = CreatePidRecord();
++		PR_ASSERT(pRec);
++		pRec->pid = op->process->md.pid;
++		pRec->state = _PR_PID_WAITING;
++		pRec->exitStatus = -1;
++		InsertPidTable(pRec);
++	    }
+ 	    pr_wp.opHead = op->next;
+ 	    if (NULL == pr_wp.opHead) {
+ 		pr_wp.opTail = NULL;
+@@ -687,20 +782,8 @@ static void WaitPidDaemonThread(void *un
+ 	}
+ #endif
+ 
+-	while (1) {
+-	    do {
+-	        pid = waitpid((pid_t) -1, &status, WNOHANG);
+-	    } while ((pid_t) -1 == pid && EINTR == errno);
+-	    if (0 == pid) break;
+-	    if ((pid_t) -1 == pid) {
+-		/* must be because we have no child processes */
+-		PR_ASSERT(ECHILD == errno);
+-		break;
+-            }
+-
+-	    PR_Lock(pr_wp.ml);
+-            ProcessReapedChildInternal(pid, status);
+-	    PR_Unlock(pr_wp.ml);
++	for (bucket = 0; bucket < NBUCKETS; ++bucket) {
++	    WaitForPidsInBucket(bucket);
+ 	}
+     }
+ }
+@@ -825,13 +908,14 @@ PRStatus _MD_DetachUnixProcess(PRProcess
+ 	pRec->state = _PR_PID_DETACHED;
+ 	InsertPidTable(pRec);
+     } else {
+-	PR_ASSERT(_PR_PID_REAPED == pRec->state);
+-	if (_PR_PID_REAPED != pRec->state) {
++	if (_PR_PID_WAITING == pRec->state) {
++	    pRec->state = _PR_PID_DETACHED;
++	} else if (_PR_PID_REAPED == pRec->state) {
++	    DeletePidTable(pRec);
++	    DeletePidRecord(pRec);
++	} else {
+ 	    PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+ 	    retVal = PR_FAILURE;
+-	} else {
+-        DeletePidTable(pRec);
+-        DeletePidRecord(pRec);
+ 	}
+     }
+     PR_DELETE(process);
+@@ -879,11 +963,32 @@ PRStatus _MD_WaitUnixProcess(
+ 	DeletePidTable(pRec);
+ 	DeletePidRecord(pRec);
+     } else {
+-	PR_ASSERT(_PR_PID_REAPED == pRec->state);
++	if (_PR_PID_WAITING == pRec->state)
++	{
++	    while (!interrupted && _PR_PID_REAPED != pRec->state) {
++		if (PR_WaitCondVar(pRec->reapedCV, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE
++		    && PR_GetError() == PR_PENDING_INTERRUPT_ERROR) {
++		    interrupted = PR_TRUE;
++		}
++	    }
++	} else if (_PR_PID_DETACHED == pRec->state) {
++	    PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
++	    retVal = PR_FAILURE;
++	    goto done;
++	} else {
++	    PR_ASSERT(_PR_PID_REAPED == pRec->state);
++	}
++
++	if (_PR_PID_REAPED == pRec->state) {
++	    if (exitCode) {
++		*exitCode = pRec->exitStatus;
++	    }
++	} else if (retVal == PR_SUCCESS) {
++	    PR_ASSERT(interrupted);
++	    retVal = PR_FAILURE;
++	}
++
+ 	DeletePidTable(pRec);
+-        if (exitCode) {
+-            *exitCode = pRec->exitStatus;
+-        }
+ 	DeletePidRecord(pRec);
+     }
+     PR_DELETE(process);
diff --git a/nspr.tar.gz b/nspr.tar.gz
new file mode 100644
index 0000000..dbd90bb
--- /dev/null
+++ b/nspr.tar.gz
Binary files differ
diff --git a/nspr.url b/nspr.url
new file mode 100644
index 0000000..d485106
--- /dev/null
+++ b/nspr.url
@@ -0,0 +1 @@
+ftp://ftp.mozilla.org/pub/nspr/releases/v4.8.6/src/nspr-4.8.6.tar.gz
diff --git a/nspr.version b/nspr.version
new file mode 100644
index 0000000..7ea5948
--- /dev/null
+++ b/nspr.version
@@ -0,0 +1 @@
+4.8.6