View | Details | Raw Unified | Return to bug 16757
Collapse All | Expand All

(-)src/main/grep.c (-5 / +67 lines)
Lines 86-91 Link Here
86
#define isRaw(x) (TYPEOF(x) == RAWSXP)
86
#define isRaw(x) (TYPEOF(x) == RAWSXP)
87
#endif
87
#endif
88
88
89
static long int max_pcre_recursions()
90
{
91
    uintptr_t ans, stack_used, current_frame;
92
    /* Approximate size of stack frame in PCRE match(), actually
93
     * platform / compiler dependent */
94
    const uintptr_t recursion_size = 600;
95
    const uintptr_t fallback_used = 10000;
96
    const long int fallback_limit = 10000;
97
    int use_recursion;
98
    pcre_config(PCRE_CONFIG_STACKRECURSE, &use_recursion);
99
    if (!use_recursion) {
100
	return -1;
101
    }
102
    if (R_CStackLimit == -1) {
103
        return fallback_limit;
104
    }
105
    current_frame = (uintptr_t) &ans;
106
    /* Approximate number of bytes used in the stack, or fallback */
107
    if (R_CStackDir == 1) {
108
	if (R_CStackStart >= current_frame) {
109
	    stack_used = R_CStackStart - current_frame;
110
	} else {
111
	    stack_used = fallback_used;
112
	}
113
    } else {
114
	if (current_frame >= R_CStackStart) {
115
	    stack_used = current_frame - R_CStackStart;
116
	} else {
117
	    stack_used = fallback_used;
118
	}
119
    }
120
    if (stack_used >= R_CStackLimit) {
121
	return 0;
122
    }
123
    ans = (R_CStackLimit - stack_used) / recursion_size;
124
    if (ans <= LONG_MAX) {
125
        return (long int) ans;
126
    } else {
127
        return -1;
128
    }
129
}
130
131
static void set_pcre_limit(pcre_extra **re_pe_ptr,
132
			   const long int recursion_limit)
133
{
134
    pcre_extra *re_pe = *re_pe_ptr;
135
    if (recursion_limit >= 0) {
136
	if (!re_pe) {
137
	    re_pe = Calloc(1, pcre_extra);
138
	    *re_pe_ptr = re_pe;
139
	    re_pe->flags = PCRE_EXTRA_MATCH_LIMIT_RECURSION;
140
	} else {
141
	    re_pe->flags = re_pe->flags | PCRE_EXTRA_MATCH_LIMIT_RECURSION;
142
	}
143
	re_pe->match_limit_recursion = recursion_limit;
144
    }
145
}
146
89
/* we allow pat == NULL if the regex cannot be safely expressed
147
/* we allow pat == NULL if the regex cannot be safely expressed
90
   as a string (e.g., when using grepRaw) */
148
   as a string (e.g., when using grepRaw) */
91
static void NORET reg_report(int rc,  regex_t *reg, const char *pat)
149
static void NORET reg_report(int rc,  regex_t *reg, const char *pat)
Lines 408-413 Link Here
408
	    re_pe = pcre_study(re_pcre, 0, &errorptr);
466
	    re_pe = pcre_study(re_pcre, 0, &errorptr);
409
	    if (errorptr)
467
	    if (errorptr)
410
		warning(_("PCRE pattern study error\n\t'%s'\n"), errorptr);
468
		warning(_("PCRE pattern study error\n\t'%s'\n"), errorptr);
469
	    set_pcre_limit(&re_pe, max_pcre_recursions());
411
470
412
	    vmax2 = vmaxget();
471
	    vmax2 = vmaxget();
413
	    for (i = itok; i < len; i += tlen) {
472
	    for (i = itok; i < len; i += tlen) {
Lines 867-878 Link Here
867
		warning(_("PCRE pattern compilation error\n\t'%s'\n\tat '%s'\n"),
926
		warning(_("PCRE pattern compilation error\n\t'%s'\n\tat '%s'\n"),
868
			errorptr, spat+erroffset);
927
			errorptr, spat+erroffset);
869
	    error(_("invalid regular expression '%s'"), spat);
928
	    error(_("invalid regular expression '%s'"), spat);
870
	    if (n > 10) {
871
		re_pe = pcre_study(re_pcre, 0, &errorptr);
872
		if (errorptr)
873
		    warning(_("PCRE pattern study error\n\t'%s'\n"), errorptr);
874
	    }
875
	}
929
	}
930
	if (n > 10) {
931
	    re_pe = pcre_study(re_pcre, 0, &errorptr);
932
	    if (errorptr)
933
		warning(_("PCRE pattern study error\n\t'%s'\n"), errorptr);
934
	}
935
	set_pcre_limit(&re_pe, max_pcre_recursions());
876
    } else {
936
    } else {
877
	int cflags = REG_NOSUB | REG_EXTENDED;
937
	int cflags = REG_NOSUB | REG_EXTENDED;
878
	if (igcase_opt) cflags |= REG_ICASE;
938
	if (igcase_opt) cflags |= REG_ICASE;
Lines 1627-1632 Link Here
1627
	    if (errorptr)
1687
	    if (errorptr)
1628
		warning(_("PCRE pattern study error\n\t'%s'\n"), errorptr);
1688
		warning(_("PCRE pattern study error\n\t'%s'\n"), errorptr);
1629
	}
1689
	}
1690
	set_pcre_limit(&re_pe, max_pcre_recursions());
1630
	replen = strlen(srep);
1691
	replen = strlen(srep);
1631
    } else {
1692
    } else {
1632
	int cflags = REG_EXTENDED;
1693
	int cflags = REG_EXTENDED;
Lines 2425-2430 Link Here
2425
	    if (errorptr)
2486
	    if (errorptr)
2426
		warning(_("PCRE pattern study error\n\t'%s'\n"), errorptr);
2487
		warning(_("PCRE pattern study error\n\t'%s'\n"), errorptr);
2427
	}
2488
	}
2489
	set_pcre_limit(&re_pe, max_pcre_recursions());
2428
	/* also extract info for named groups */
2490
	/* also extract info for named groups */
2429
	pcre_fullinfo(re_pcre, re_pe, PCRE_INFO_NAMECOUNT, &name_count);
2491
	pcre_fullinfo(re_pcre, re_pe, PCRE_INFO_NAMECOUNT, &name_count);
2430
	pcre_fullinfo(re_pcre, re_pe, PCRE_INFO_NAMEENTRYSIZE, &name_entry_size);
2492
	pcre_fullinfo(re_pcre, re_pe, PCRE_INFO_NAMEENTRYSIZE, &name_entry_size);

Return to bug 16757