changeset 36822:882657a9f768

xdiff: replace {unsigned ,}long with {u,}int64_t MSVC treats "long" as 4-byte. That could cause overflows since the xdiff code uses "long" in places where "size_t" or "ssize_t" should be used. Let's use explicit 8 byte integers to avoid FWIW git avoids that overflow by limiting diff size to 1GB [1]. After examining the code, I think the remaining risk (the use of "int") is low since "int" is only used for return values and hash table size. Although a wrong hash table size would not affect the correctness of the code, but that could make the code extremely slow. The next patch will change hash table size to 8-byte integer so the 1GB limit is unlikely needed. This patch was done by using `sed`. [1]: https://github.com/git/git/commit/dcd1742e56ebb944c4ff62346da4548e1e3be67 Differential Revision: https://phab.mercurial-scm.org/D2762
author Jun Wu <quark@fb.com>
date Fri, 09 Mar 2018 14:24:27 -0800
parents 0c7350656f93
children 49fe6249937a
files mercurial/thirdparty/xdiff/xdiff.h mercurial/thirdparty/xdiff/xdiffi.c mercurial/thirdparty/xdiff/xdiffi.h mercurial/thirdparty/xdiff/xinclude.h mercurial/thirdparty/xdiff/xprepare.c mercurial/thirdparty/xdiff/xtypes.h mercurial/thirdparty/xdiff/xutils.c mercurial/thirdparty/xdiff/xutils.h
diffstat 8 files changed, 118 insertions(+), 117 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/thirdparty/xdiff/xdiff.h	Sun Mar 04 11:30:16 2018 -0800
+++ b/mercurial/thirdparty/xdiff/xdiff.h	Fri Mar 09 14:24:27 2018 -0800
@@ -40,28 +40,28 @@
 
 typedef struct s_mmfile {
 	char *ptr;
-	long size;
+	int64_t size;
 } mmfile_t;
 
 typedef struct s_mmbuffer {
 	char *ptr;
-	long size;
+	int64_t size;
 } mmbuffer_t;
 
 typedef struct s_xpparam {
-	unsigned long flags;
+	uint64_t flags;
 } xpparam_t;
 
 typedef struct s_xdemitcb {
 	void *priv;
 } xdemitcb_t;
 
-typedef int (*xdl_emit_hunk_consume_func_t)(long start_a, long count_a,
-					    long start_b, long count_b,
+typedef int (*xdl_emit_hunk_consume_func_t)(int64_t start_a, int64_t count_a,
+					    int64_t start_b, int64_t count_b,
 					    void *cb_data);
 
 typedef struct s_xdemitconf {
-	unsigned long flags;
+	uint64_t flags;
 	xdl_emit_hunk_consume_func_t hunk_func;
 } xdemitconf_t;
 
@@ -70,8 +70,8 @@
 #define xdl_free(ptr) free(ptr)
 #define xdl_realloc(ptr,x) realloc(ptr,x)
 
-void *xdl_mmfile_first(mmfile_t *mmf, long *size);
-long xdl_mmfile_size(mmfile_t *mmf);
+void *xdl_mmfile_first(mmfile_t *mmf, int64_t *size);
+int64_t xdl_mmfile_size(mmfile_t *mmf);
 
 int xdl_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
 	     xdemitconf_t const *xecfg, xdemitcb_t *ecb);
--- a/mercurial/thirdparty/xdiff/xdiffi.c	Sun Mar 04 11:30:16 2018 -0800
+++ b/mercurial/thirdparty/xdiff/xdiffi.c	Fri Mar 09 14:24:27 2018 -0800
@@ -37,18 +37,18 @@
 
 
 typedef struct s_xdpsplit {
-	long i1, i2;
+	int64_t i1, i2;
 	int min_lo, min_hi;
 } xdpsplit_t;
 
 
 
 
-static long xdl_split(unsigned long const *ha1, long off1, long lim1,
-		      unsigned long const *ha2, long off2, long lim2,
-		      long *kvdf, long *kvdb, int need_min, xdpsplit_t *spl,
+static int64_t xdl_split(uint64_t const *ha1, int64_t off1, int64_t lim1,
+		      uint64_t const *ha2, int64_t off2, int64_t lim2,
+		      int64_t *kvdf, int64_t *kvdb, int need_min, xdpsplit_t *spl,
 		      xdalgoenv_t *xenv);
-static xdchange_t *xdl_add_change(xdchange_t *xscr, long i1, long i2, long chg1, long chg2);
+static xdchange_t *xdl_add_change(xdchange_t *xscr, int64_t i1, int64_t i2, int64_t chg1, int64_t chg2);
 
 
 
@@ -63,16 +63,16 @@
  * cases using this algorithm is full, so a little bit of heuristic is needed
  * to cut the search and to return a suboptimal point.
  */
-static long xdl_split(unsigned long const *ha1, long off1, long lim1,
-		      unsigned long const *ha2, long off2, long lim2,
-		      long *kvdf, long *kvdb, int need_min, xdpsplit_t *spl,
+static int64_t xdl_split(uint64_t const *ha1, int64_t off1, int64_t lim1,
+		      uint64_t const *ha2, int64_t off2, int64_t lim2,
+		      int64_t *kvdf, int64_t *kvdb, int need_min, xdpsplit_t *spl,
 		      xdalgoenv_t *xenv) {
-	long dmin = off1 - lim2, dmax = lim1 - off2;
-	long fmid = off1 - off2, bmid = lim1 - lim2;
-	long odd = (fmid - bmid) & 1;
-	long fmin = fmid, fmax = fmid;
-	long bmin = bmid, bmax = bmid;
-	long ec, d, i1, i2, prev1, best, dd, v, k;
+	int64_t dmin = off1 - lim2, dmax = lim1 - off2;
+	int64_t fmid = off1 - off2, bmid = lim1 - lim2;
+	int64_t odd = (fmid - bmid) & 1;
+	int64_t fmin = fmid, fmax = fmid;
+	int64_t bmin = bmid, bmax = bmid;
+	int64_t ec, d, i1, i2, prev1, best, dd, v, k;
 
 	/*
 	 * Set initial diagonal values for both forward and backward path.
@@ -221,7 +221,7 @@
 		 * the furthest reaching path using the (i1 + i2) measure.
 		 */
 		if (ec >= xenv->mxcost) {
-			long fbest, fbest1, bbest, bbest1;
+			int64_t fbest, fbest1, bbest, bbest1;
 
 			fbest = fbest1 = -1;
 			for (d = fmax; d >= fmin; d -= 2) {
@@ -269,10 +269,10 @@
  * the box splitting function. Note that the real job (marking changed lines)
  * is done in the two boundary reaching checks.
  */
-int xdl_recs_cmp(diffdata_t *dd1, long off1, long lim1,
-		 diffdata_t *dd2, long off2, long lim2,
-		 long *kvdf, long *kvdb, int need_min, xdalgoenv_t *xenv) {
-	unsigned long const *ha1 = dd1->ha, *ha2 = dd2->ha;
+int xdl_recs_cmp(diffdata_t *dd1, int64_t off1, int64_t lim1,
+		 diffdata_t *dd2, int64_t off2, int64_t lim2,
+		 int64_t *kvdf, int64_t *kvdb, int need_min, xdalgoenv_t *xenv) {
+	uint64_t const *ha1 = dd1->ha, *ha2 = dd2->ha;
 
 	/*
 	 * Shrink the box by walking through each diagonal snake (SW and NE).
@@ -286,13 +286,13 @@
 	 */
 	if (off1 == lim1) {
 		char *rchg2 = dd2->rchg;
-		long *rindex2 = dd2->rindex;
+		int64_t *rindex2 = dd2->rindex;
 
 		for (; off2 < lim2; off2++)
 			rchg2[rindex2[off2]] = 1;
 	} else if (off2 == lim2) {
 		char *rchg1 = dd1->rchg;
-		long *rindex1 = dd1->rindex;
+		int64_t *rindex1 = dd1->rindex;
 
 		for (; off1 < lim1; off1++)
 			rchg1[rindex1[off1]] = 1;
@@ -327,8 +327,8 @@
 
 int xdl_do_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
 		xdfenv_t *xe) {
-	long ndiags;
-	long *kvd, *kvdf, *kvdb;
+	int64_t ndiags;
+	int64_t *kvd, *kvdf, *kvdb;
 	xdalgoenv_t xenv;
 	diffdata_t dd1, dd2;
 
@@ -342,7 +342,7 @@
 	 * One is to store the forward path and one to store the backward path.
 	 */
 	ndiags = xe->xdf1.nreff + xe->xdf2.nreff + 3;
-	if (!(kvd = (long *) xdl_malloc((2 * ndiags + 2) * sizeof(long)))) {
+	if (!(kvd = (int64_t *) xdl_malloc((2 * ndiags + 2) * sizeof(long)))) {
 
 		xdl_free_env(xe);
 		return -1;
@@ -381,7 +381,7 @@
 }
 
 
-static xdchange_t *xdl_add_change(xdchange_t *xscr, long i1, long i2, long chg1, long chg2) {
+static xdchange_t *xdl_add_change(xdchange_t *xscr, int64_t i1, int64_t i2, int64_t chg1, int64_t chg2) {
 	xdchange_t *xch;
 
 	if (!(xch = (xdchange_t *) xdl_malloc(sizeof(xdchange_t))))
@@ -398,7 +398,7 @@
 }
 
 
-static int recs_match(xrecord_t *rec1, xrecord_t *rec2, long flags)
+static int recs_match(xrecord_t *rec1, xrecord_t *rec2, int64_t flags)
 {
 	return (rec1->ha == rec2->ha &&
 		xdl_recmatch(rec1->ptr, rec1->size,
@@ -421,7 +421,7 @@
  */
 static int get_indent(xrecord_t *rec)
 {
-	long i;
+	int64_t i;
 	int ret = 0;
 
 	for (i = 0; i < rec->size; i++) {
@@ -497,10 +497,10 @@
 /*
  * Fill m with information about a hypothetical split of xdf above line split.
  */
-static void measure_split(const xdfile_t *xdf, long split,
+static void measure_split(const xdfile_t *xdf, int64_t split,
 			  struct split_measurement *m)
 {
-	long i;
+	int64_t i;
 
 	if (split >= xdf->nrec) {
 		m->end_of_file = 1;
@@ -706,13 +706,13 @@
 	 * The index of the first changed line in the group, or the index of
 	 * the unchanged line above which the (empty) group is located.
 	 */
-	long start;
+	int64_t start;
 
 	/*
 	 * The index of the first unchanged line after the group. For an empty
 	 * group, end is equal to start.
 	 */
-	long end;
+	int64_t end;
 };
 
 /*
@@ -762,7 +762,7 @@
  * following group, expand this group to include it. Return 0 on success or -1
  * if g cannot be slid down.
  */
-static int group_slide_down(xdfile_t *xdf, struct xdlgroup *g, long flags)
+static int group_slide_down(xdfile_t *xdf, struct xdlgroup *g, int64_t flags)
 {
 	if (g->end < xdf->nrec &&
 	    recs_match(xdf->recs[g->start], xdf->recs[g->end], flags)) {
@@ -783,7 +783,7 @@
  * into a previous group, expand this group to include it. Return 0 on success
  * or -1 if g cannot be slid up.
  */
-static int group_slide_up(xdfile_t *xdf, struct xdlgroup *g, long flags)
+static int group_slide_up(xdfile_t *xdf, struct xdlgroup *g, int64_t flags)
 {
 	if (g->start > 0 &&
 	    recs_match(xdf->recs[g->start - 1], xdf->recs[g->end - 1], flags)) {
@@ -818,10 +818,10 @@
  * This also helps in finding joinable change groups and reducing the diff
  * size.
  */
-int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags) {
+int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, int64_t flags) {
 	struct xdlgroup g, go;
-	long earliest_end, end_matching_other;
-	long groupsize;
+	int64_t earliest_end, end_matching_other;
+	int64_t groupsize;
 
 	group_init(xdf, &g);
 	group_init(xdfo, &go);
@@ -906,7 +906,7 @@
 			 * "score" for each position that the group can be shifted
 			 * to. Then we pick the shift with the lowest score.
 			 */
-			long shift, best_shift = -1;
+			int64_t shift, best_shift = -1;
 			struct split_score best_score;
 
 			/*
@@ -975,7 +975,7 @@
 int xdl_build_script(xdfenv_t *xe, xdchange_t **xscr) {
 	xdchange_t *cscr = NULL, *xch;
 	char *rchg1 = xe->xdf1.rchg, *rchg2 = xe->xdf2.rchg;
-	long i1, i2, l1, l2;
+	int64_t i1, i2, l1, l2;
 
 	/*
 	 * Trivial. Collects "groups" of changes and creates an edit script.
@@ -1016,9 +1016,9 @@
 xdchange_t *xdl_get_hunk(xdchange_t **xscr, xdemitconf_t const *xecfg)
 {
 	xdchange_t *xch, *xchp, *lxch;
-	long max_common = 0;
-	long max_ignorable = 0;
-	unsigned long ignored = 0; /* number of ignored blank lines */
+	int64_t max_common = 0;
+	int64_t max_ignorable = 0;
+	uint64_t ignored = 0; /* number of ignored blank lines */
 
 	/* remove ignorable changes that are too far before other changes */
 	for (xchp = *xscr; xchp && xchp->ignore; xchp = xchp->next) {
@@ -1035,7 +1035,7 @@
 	lxch = *xscr;
 
 	for (xchp = *xscr, xch = xchp->next; xch; xchp = xch, xch = xch->next) {
-		long distance = xch->i1 - (xchp->i1 + xchp->chg1);
+		int64_t distance = xch->i1 - (xchp->i1 + xchp->chg1);
 		if (distance > max_common)
 			break;
 
@@ -1062,14 +1062,14 @@
 static int xdl_call_hunk_func(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
 			      xdemitconf_t const *xecfg)
 {
-	long p = xe->nprefix, s = xe->nsuffix;
+	int64_t p = xe->nprefix, s = xe->nsuffix;
 	xdchange_t *xch, *xche;
 
 	if (!xecfg->hunk_func)
 		return -1;
 
 	if ((xecfg->flags & XDL_EMIT_BDIFFHUNK) != 0) {
-		long i1 = 0, i2 = 0, n1 = xe->xdf1.nrec, n2 = xe->xdf2.nrec;
+		int64_t i1 = 0, i2 = 0, n1 = xe->xdf1.nrec, n2 = xe->xdf2.nrec;
 		for (xch = xscr; xch; xch = xche->next) {
 			xche = xdl_get_hunk(&xch, xecfg);
 			if (!xch)
--- a/mercurial/thirdparty/xdiff/xdiffi.h	Sun Mar 04 11:30:16 2018 -0800
+++ b/mercurial/thirdparty/xdiff/xdiffi.h	Fri Mar 09 14:24:27 2018 -0800
@@ -25,33 +25,33 @@
 
 
 typedef struct s_diffdata {
-	long nrec;
-	unsigned long const *ha;
-	long *rindex;
+	int64_t nrec;
+	uint64_t const *ha;
+	int64_t *rindex;
 	char *rchg;
 } diffdata_t;
 
 typedef struct s_xdalgoenv {
-	long mxcost;
-	long snake_cnt;
-	long heur_min;
+	int64_t mxcost;
+	int64_t snake_cnt;
+	int64_t heur_min;
 } xdalgoenv_t;
 
 typedef struct s_xdchange {
 	struct s_xdchange *next;
-	long i1, i2;
-	long chg1, chg2;
+	int64_t i1, i2;
+	int64_t chg1, chg2;
 	int ignore;
 } xdchange_t;
 
 
 
-int xdl_recs_cmp(diffdata_t *dd1, long off1, long lim1,
-		 diffdata_t *dd2, long off2, long lim2,
-		 long *kvdf, long *kvdb, int need_min, xdalgoenv_t *xenv);
+int xdl_recs_cmp(diffdata_t *dd1, int64_t off1, int64_t lim1,
+		 diffdata_t *dd2, int64_t off2, int64_t lim2,
+		 int64_t *kvdf, int64_t *kvdb, int need_min, xdalgoenv_t *xenv);
 int xdl_do_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
 		xdfenv_t *xe);
-int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags);
+int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, int64_t flags);
 int xdl_build_script(xdfenv_t *xe, xdchange_t **xscr);
 void xdl_free_script(xdchange_t *xscr);
 
--- a/mercurial/thirdparty/xdiff/xinclude.h	Sun Mar 04 11:30:16 2018 -0800
+++ b/mercurial/thirdparty/xdiff/xinclude.h	Fri Mar 09 14:24:27 2018 -0800
@@ -24,6 +24,7 @@
 #define XINCLUDE_H
 
 #include <ctype.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
--- a/mercurial/thirdparty/xdiff/xprepare.c	Sun Mar 04 11:30:16 2018 -0800
+++ b/mercurial/thirdparty/xdiff/xprepare.c	Fri Mar 09 14:24:27 2018 -0800
@@ -31,35 +31,35 @@
 
 typedef struct s_xdlclass {
 	struct s_xdlclass *next;
-	unsigned long ha;
+	uint64_t ha;
 	char const *line;
-	long size;
-	long idx;
-	long len1, len2;
+	int64_t size;
+	int64_t idx;
+	int64_t len1, len2;
 } xdlclass_t;
 
 typedef struct s_xdlclassifier {
 	unsigned int hbits;
-	long hsize;
+	int64_t hsize;
 	xdlclass_t **rchash;
 	chastore_t ncha;
 	xdlclass_t **rcrecs;
-	long alloc;
-	long count;
-	long flags;
+	int64_t alloc;
+	int64_t count;
+	int64_t flags;
 } xdlclassifier_t;
 
 
 
 
-static int xdl_init_classifier(xdlclassifier_t *cf, long size, long flags);
+static int xdl_init_classifier(xdlclassifier_t *cf, int64_t size, int64_t flags);
 static void xdl_free_classifier(xdlclassifier_t *cf);
 static int xdl_classify_record(unsigned int pass, xdlclassifier_t *cf, xrecord_t **rhash,
 			       unsigned int hbits, xrecord_t *rec);
-static int xdl_prepare_ctx(unsigned int pass, mmfile_t *mf, long narec, xpparam_t const *xpp,
+static int xdl_prepare_ctx(unsigned int pass, mmfile_t *mf, int64_t narec, xpparam_t const *xpp,
 			   xdlclassifier_t *cf, xdfile_t *xdf);
 static void xdl_free_ctx(xdfile_t *xdf);
-static int xdl_clean_mmatch(char const *dis, long i, long s, long e);
+static int xdl_clean_mmatch(char const *dis, int64_t i, int64_t s, int64_t e);
 static int xdl_cleanup_records(xdlclassifier_t *cf, xdfile_t *xdf1, xdfile_t *xdf2);
 static int xdl_trim_ends(xdfile_t *xdf1, xdfile_t *xdf2);
 static int xdl_optimize_ctxs(xdlclassifier_t *cf, xdfile_t *xdf1, xdfile_t *xdf2);
@@ -67,7 +67,7 @@
 
 
 
-static int xdl_init_classifier(xdlclassifier_t *cf, long size, long flags) {
+static int xdl_init_classifier(xdlclassifier_t *cf, int64_t size, int64_t flags) {
 	cf->flags = flags;
 
 	cf->hbits = xdl_hashbits((unsigned int) size);
@@ -108,7 +108,7 @@
 
 static int xdl_classify_record(unsigned int pass, xdlclassifier_t *cf, xrecord_t **rhash,
 			       unsigned int hbits, xrecord_t *rec) {
-	long hi;
+	int64_t hi;
 	char const *line;
 	xdlclass_t *rcrec;
 	xdlclass_t **rcrecs;
@@ -163,11 +163,11 @@
  * outweighs the shift change. A diff result with suboptimal shifting is still
  * valid.
  */
-static void xdl_trim_files(mmfile_t *mf1, mmfile_t *mf2, long reserved,
+static void xdl_trim_files(mmfile_t *mf1, mmfile_t *mf2, int64_t reserved,
 		xdfenv_t *xe, mmfile_t *out_mf1, mmfile_t *out_mf2) {
 	mmfile_t msmall, mlarge;
 	/* prefix lines, prefix bytes, suffix lines, suffix bytes */
-	long plines = 0, pbytes = 0, slines = 0, sbytes = 0, i;
+	int64_t plines = 0, pbytes = 0, slines = 0, sbytes = 0, i;
 	/* prefix char pointer for msmall and mlarge */
 	const char *pp1, *pp2;
 	/* suffix char pointer for msmall and mlarge */
@@ -237,18 +237,18 @@
 }
 
 
-static int xdl_prepare_ctx(unsigned int pass, mmfile_t *mf, long narec, xpparam_t const *xpp,
+static int xdl_prepare_ctx(unsigned int pass, mmfile_t *mf, int64_t narec, xpparam_t const *xpp,
 			   xdlclassifier_t *cf, xdfile_t *xdf) {
 	unsigned int hbits;
-	long nrec, hsize, bsize;
-	unsigned long hav;
+	int64_t nrec, hsize, bsize;
+	uint64_t hav;
 	char const *blk, *cur, *top, *prev;
 	xrecord_t *crec;
 	xrecord_t **recs, **rrecs;
 	xrecord_t **rhash;
-	unsigned long *ha;
+	uint64_t *ha;
 	char *rchg;
-	long *rindex;
+	int64_t *rindex;
 
 	ha = NULL;
 	rindex = NULL;
@@ -296,9 +296,9 @@
 		goto abort;
 	memset(rchg, 0, (nrec + 2) * sizeof(char));
 
-	if (!(rindex = (long *) xdl_malloc((nrec + 1) * sizeof(long))))
+	if (!(rindex = (int64_t *) xdl_malloc((nrec + 1) * sizeof(long))))
 		goto abort;
-	if (!(ha = (unsigned long *) xdl_malloc((nrec + 1) * sizeof(unsigned long))))
+	if (!(ha = (uint64_t *) xdl_malloc((nrec + 1) * sizeof(unsigned long))))
 		goto abort;
 
 	xdf->nrec = nrec;
@@ -340,7 +340,7 @@
 
 int xdl_prepare_env(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
 		    xdfenv_t *xe) {
-	long enl1, enl2, sample;
+	int64_t enl1, enl2, sample;
 	mmfile_t tmf1, tmf2;
 	xdlclassifier_t cf;
 
@@ -388,8 +388,8 @@
 }
 
 
-static int xdl_clean_mmatch(char const *dis, long i, long s, long e) {
-	long r, rdis0, rpdis0, rdis1, rpdis1;
+static int xdl_clean_mmatch(char const *dis, int64_t i, int64_t s, int64_t e) {
+	int64_t r, rdis0, rpdis0, rdis1, rpdis1;
 
 	/*
 	 * Limits the window the is examined during the similar-lines
@@ -452,7 +452,7 @@
  * might be potentially discarded if they happear in a run of discardable.
  */
 static int xdl_cleanup_records(xdlclassifier_t *cf, xdfile_t *xdf1, xdfile_t *xdf2) {
-	long i, nm, nreff, mlim;
+	int64_t i, nm, nreff, mlim;
 	xrecord_t **recs;
 	xdlclass_t *rcrec;
 	char *dis, *dis1, *dis2;
@@ -515,7 +515,7 @@
  * Early trim initial and terminal matching records.
  */
 static int xdl_trim_ends(xdfile_t *xdf1, xdfile_t *xdf2) {
-	long i, lim;
+	int64_t i, lim;
 	xrecord_t **recs1, **recs2;
 
 	recs1 = xdf1->recs;
--- a/mercurial/thirdparty/xdiff/xtypes.h	Sun Mar 04 11:30:16 2018 -0800
+++ b/mercurial/thirdparty/xdiff/xtypes.h	Fri Mar 09 14:24:27 2018 -0800
@@ -27,22 +27,22 @@
 
 typedef struct s_chanode {
 	struct s_chanode *next;
-	long icurr;
+	int64_t icurr;
 } chanode_t;
 
 typedef struct s_chastore {
 	chanode_t *head, *tail;
-	long isize, nsize;
+	int64_t isize, nsize;
 	chanode_t *ancur;
 	chanode_t *sncur;
-	long scurr;
+	int64_t scurr;
 } chastore_t;
 
 typedef struct s_xrecord {
 	struct s_xrecord *next;
 	char const *ptr;
-	long size;
-	unsigned long ha;
+	int64_t size;
+	uint64_t ha;
 } xrecord_t;
 
 typedef struct s_xdfile {
@@ -50,7 +50,7 @@
 	chastore_t rcha;
 
 	/* number of records (lines) */
-	long nrec;
+	int64_t nrec;
 
 	/* hash table size
 	 * the maximum hash value in the table is (1 << hbits) */
@@ -64,7 +64,7 @@
 	 * [recs[i] for i in range(0, dstart)] are common prefix.
 	 * [recs[i] for i in range(dstart, dend + 1 - dstart)] are interesting
 	 * lines */
-	long dstart, dend;
+	int64_t dstart, dend;
 
 	/* pointer to records (lines) */
 	xrecord_t **recs;
@@ -82,14 +82,14 @@
 	 * rindex[0] is likely dstart, if not removed up by rule 2.
 	 * rindex[nreff - 1] is likely dend, if not removed by rule 2.
 	 */
-	long *rindex;
+	int64_t *rindex;
 
 	/* rindex size */
-	long nreff;
+	int64_t nreff;
 
 	/* cleaned-up record index => hash value
 	 * ha[i] = recs[rindex[i]]->ha */
-	unsigned long *ha;
+	uint64_t *ha;
 } xdfile_t;
 
 typedef struct s_xdfenv {
@@ -97,7 +97,7 @@
 
 	/* number of lines for common prefix and suffix that are removed
 	 * from xdf1 and xdf2 as a preprocessing step */
-	long nprefix, nsuffix;
+	int64_t nprefix, nsuffix;
 } xdfenv_t;
 
 
--- a/mercurial/thirdparty/xdiff/xutils.c	Sun Mar 04 11:30:16 2018 -0800
+++ b/mercurial/thirdparty/xdiff/xutils.c	Fri Mar 09 14:24:27 2018 -0800
@@ -27,8 +27,8 @@
 
 
 
-long xdl_bogosqrt(long n) {
-	long i;
+int64_t xdl_bogosqrt(int64_t n) {
+	int64_t i;
 
 	/*
 	 * Classical integer square root approximation using shifts.
@@ -40,20 +40,20 @@
 }
 
 
-void *xdl_mmfile_first(mmfile_t *mmf, long *size)
+void *xdl_mmfile_first(mmfile_t *mmf, int64_t *size)
 {
 	*size = mmf->size;
 	return mmf->ptr;
 }
 
 
-long xdl_mmfile_size(mmfile_t *mmf)
+int64_t xdl_mmfile_size(mmfile_t *mmf)
 {
 	return mmf->size;
 }
 
 
-int xdl_cha_init(chastore_t *cha, long isize, long icount) {
+int xdl_cha_init(chastore_t *cha, int64_t isize, int64_t icount) {
 
 	cha->head = cha->tail = NULL;
 	cha->isize = isize;
@@ -100,8 +100,8 @@
 	return data;
 }
 
-long xdl_guess_lines(mmfile_t *mf, long sample) {
-	long nl = 0, size, tsize = 0;
+int64_t xdl_guess_lines(mmfile_t *mf, int64_t sample) {
+	int64_t nl = 0, size, tsize = 0;
 	char const *data, *cur, *top;
 
 	if ((cur = data = xdl_mmfile_first(mf, &size)) != NULL) {
@@ -121,15 +121,15 @@
 	return nl + 1;
 }
 
-int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags)
+int xdl_recmatch(const char *l1, int64_t s1, const char *l2, int64_t s2, int64_t flags)
 {
 	if (s1 == s2 && !memcmp(l1, l2, s1))
 		return 1;
 	return 0;
 }
 
-unsigned long xdl_hash_record(char const **data, char const *top, long flags) {
-	unsigned long ha = 5381;
+uint64_t xdl_hash_record(char const **data, char const *top, int64_t flags) {
+	uint64_t ha = 5381;
 	char const *ptr = *data;
 
 	for (; ptr < top && *ptr != '\n'; ptr++) {
--- a/mercurial/thirdparty/xdiff/xutils.h	Sun Mar 04 11:30:16 2018 -0800
+++ b/mercurial/thirdparty/xdiff/xutils.h	Fri Mar 09 14:24:27 2018 -0800
@@ -25,13 +25,13 @@
 
 
 
-long xdl_bogosqrt(long n);
-int xdl_cha_init(chastore_t *cha, long isize, long icount);
+int64_t xdl_bogosqrt(int64_t n);
+int xdl_cha_init(chastore_t *cha, int64_t isize, int64_t icount);
 void xdl_cha_free(chastore_t *cha);
 void *xdl_cha_alloc(chastore_t *cha);
-long xdl_guess_lines(mmfile_t *mf, long sample);
-int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags);
-unsigned long xdl_hash_record(char const **data, char const *top, long flags);
+int64_t xdl_guess_lines(mmfile_t *mf, int64_t sample);
+int xdl_recmatch(const char *l1, int64_t s1, const char *l2, int64_t s2, int64_t flags);
+uint64_t xdl_hash_record(char const **data, char const *top, int64_t flags);
 unsigned int xdl_hashbits(unsigned int size);