unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#24751: 26.0.50; Regex stack overflow not detected properly (gets "Variable binding depth exceeds max-specpdl-size")
@ 2016-10-21  3:54 npostavs
  2016-11-04  8:22 ` Eli Zaretskii
  0 siblings, 1 reply; 22+ messages in thread
From: npostavs @ 2016-10-21  3:54 UTC (permalink / raw)
  To: 24751

[-- Attachment #1: Type: text/plain, Size: 356 bytes --]


This is a followup from Bug #24358, since that thread filled up with
messages about the crash in 25.1, so I'm opening a new bug for the wrong
regex stack overflow check (this affects only the master branch).

To reproduce the error run (re-search-forward ".*\\(\n.*\\)*" nil t) in
a buffer with contents of the attached bug-24358-regex-max-specpdl.txt.

 

[-- Attachment #2: sample data for regex test --]
[-- Type: text/plain, Size: 41457 bytes --]

DESCRIPTION;LANGUAGE=en-US:Nn Nnnnn\,\n\nNnnnnnnnn nnn nnn nnnnnn nn nnnnnn
 nnnnnnn nnnn nnnnnnnnn. N nnnn nnnnnnnnn nn nnn nnnnnnnn nnnnnnn nnn nn nn
 nn nn-nnnnnnn nn Nnnnnnn nn 99.99 NNNN\n\nNnnn nnnnnnn\,\n\nNnnnn Nnnnnnnn
  | Nnnnnnnnnn Nnnnnnnn Nnnnn Nnnnnn\n\nNNN Nnnnnn Nnnnnnn\nNnnn Nnnnn Nnnn
 n\,\n99 Nnnnnnnnnn Nnnnnn\,\nNnnnnn\, NN9N 9NN\n+999999999999 | Nnnn: nnnn
 nnnnn@nnn.nnn\nnnnnnnnnn@nnn.nnn | nnn.nnn.nnn\n\n\n\n\n__________________
 ___________________________\nNnnn: Nnnnn N. Nnnnnnnnnnn [nnnnnn:nnn@nnnnnn
 nn.nn]\nNnnn: 99 Nnnnnn 9999 9:99 NN\nNn: NNN Nnnnnn <NNNNnnnnn@nnn.nnn>\n
 Nn: Nnnn Nnnnn <nnnnnn@nnn.nnn>\; Nnnn Nnnnnnnn <nnnnnnnnn@nnn.nnn>\; +NNN
 N <NNNN@nnn.nnn>\; +NN Nnnnnn <Nnnnnnnn@nnn.nnn>\nNnnnnnn: Nn: [NNN] Nn: N
 nnnnnn nnnnnnn nn NNN\n\n\nNnnnn\, N nnnn'n nnn nnn nnnn nnnnn nnn.  99:99
  NNN nnn nnnnnn\, nnn 99:99 NNN nn nnnnnn nn nn n nnnnnn\, nnn N'n nnnnn n
 nnnnnnnn. :)\n\n--\nNnn/Nnnnnnn\nNnnnn N. Nnnnnnnnnnn\nNnnnnnnn Nnnn NN\n\
 nNn Nnn\, Nnn 99 9999 nn 99:99\, NNN Nnnnnn nnnnn:\n\n> Nn Nnnnn\,\n>\n> N
 nnn nnn'nn nnnnnn n nnnn nnnn.\n>\n> Nnnnn nn nn nnnnnnnn nn nnnn Nnnnnnnn
 nnnnn nnnn nnnn nn nnnn nn 9.99nn NNN nnnnn?\n>\n> Nnnn nnnnnnn\,\n>\n> Nn
 nnn Nnnnnnnn | Nnnnnnnnnn Nnnnnnnn Nnnnn Nnnnnn\n>\n> NNN Nnnnnn Nnnnnnn\n
 > Nnnn Nnnnn Nnnnn\,\n> 99 Nnnnnnnnnn Nnnnnn\,\n> Nnnnnn\, NN9N 9NN\n> +99
 9999999999 | Nnnn: nnnnnnnnn@nnn.nnn\n> nnnnnnnnn@nnn.nnn | nnn.nnn.nnn\n>
 \n> -----Nnnnnnnn Nnnnnnn-----\n> Nnnn: NNN Nnnnnn\n> Nnnn: 99 Nnnnnn 9999
  9:99 NN\n> Nn: 'Nnnnn N. Nnnnnnnnnnn' <nnn@nnnnnnnn.nn>\; NNN Nnnnnn\n> <
 NNNNnnnnn@nnn.nnn>\n> Nn: Nnnn Nnnnn <nnnnnn@nnn.nnn>\; Nnnn Nnnnnnnn <nnn
 nnnnnn@nnn.nnn>\;\n> +NNNN <NNNN@nnn.nnn>\; +NN Nnnnnn <Nnnnnnnn@nnn.nnn>\
 n> Nnnnnnn: NN: [NNN] Nn: Nnnnnnn nnnnnnn nn NNN\n>\n> NN Nnnnn\,\n>\n> Nn
 nnnnnnn nnnnn nnn nn. Nnnnnn 9nn NNN nnnnn nn nnnnn. N nnnn nnnn nnn.\n>\n
 > N’nn nnnnnnn nnn n nnnnnnn nnnnnn nnn nnnn nnnnnnnn nnnnnnn.\n>\n> Nnn
 n nnnnnnn\,\n>\n> Nnnnn Nnnnnnnn | Nnnnnnnnnn Nnnnnnnn Nnnnn Nnnnnn\n>\n> 
 NNN Nnnnnn Nnnnnnn\n> Nnnn Nnnnn Nnnnn\,\n> 99 Nnnnnnnnnn Nnnnnn\,\n> Nnnn
 nn\, NN9N 9NN\n> +999999999999 | Nnnn: nnnnnnnnn@nnn.nnn\n> nnnnnnnnn@nnn.
 nnn | nnn.nnn.nnn\n>\n> -----Nnnnnnnn Nnnnnnn-----\n> Nnnn: Nnnnn N. Nnnnn
 nnnnnn [nnnnnn:nnn@nnnnnnnn.nn]\n> Nnnn: 99 Nnnnnn 9999 9:99 NN\n> Nn: NNN
  Nnnnnn <NNNNnnnnn@nnn.nnn>\n> Nn: Nnnn Nnnnn <nnnnnn@nnn.nnn>\; Nnnn Nnnn
 nnnn <nnnnnnnnn@nnn.nnn>\;\n> +NNNN <NNNN@nnn.nnn>\; +NN Nnnnnn <Nnnnnnnn@
 nnn.nnn>\n> Nnnnnnn: Nn: [NNN] Nn: Nnnnnnn nnnnnnn nn NNN\n>\n> Nn\, Nnnnn
 .\n>\n> Nnnnnn nnnnnnn Nnnnnnnnn nnnn nnnn nn nnnn nnn nn\, nnnnnnnnn nn n
 nnn\n> nnnn nn nnnn nnnnn nnn nnnn nnnnn.  Nn nn nnnn nn nnnn nnnnn NN nnn
 nn\,\n> nn nnn nn nn nnn nnnnn nnn nnnn?  Nnnnnnn nnnnn 99 NNN nnnnn nnn n
 n.\n>\n> Nnnnnn N nnnn nnn nn nnnn nnn nnnn nn?  Nn nnnnnn nnnn nn +99 999
 9 9999.\n>\n> --\n> Nnn/Nnnnnnn\n> Nnnnn N. Nnnnnnnnnnn\n> Nnnnnnnn Nnnn N
 N\n>\n> Nn Nnn\, Nnn 99 9999 nn 99:99\, NNN Nnnnnn nnnnn:\n>\n>> Nn Nnnnn\
 ,\n>>\n>> Nnnnn\, nnnn nnnnnnn nnn nnnn nnnnnnnnnnnn nn nnn nnnn. Nnnn nn 
 nnn nnnnnnn nnnn nnnnnn nn nnnn nn nnnnnn nnnnnnnnn nnn NNN nnnnnnnnn.\n>>
 \n>> Nn nnnnn nn nnnn nn nnnn nnnn nnnnnnnnn nnnn nnn nnnnnnnnnnnnn nnnnnn
 \n>> nnnnn N nnnn nnnnnnnn. N nnnnn nnnnnn nn nnnnn nnn nnnnnnnn nnnnn\,\n
 >> nnnn nnnn / nnnnnnnnnn nnnnnnnnn nnn nnnn nnnnnn nnnnnnnnn nnn nnn\n>> 
 nnnnnn / nnnnnnn / nnnnnn nnnnnnnnnnnnn\, nnnnnnnn nnnnn nnnnnn 99\n>> nnn
 nnnn nnnn n nnnnn nnnn. Nnnn nn nnnn nnnnn nnnnnn nnn nn nnn nnnnn\n>> nnn
 nnnn nnnn nnnnnnnnnn.\n>>\n>> Nnnnnn nnn nn nnnn nnnn nnnnnnnnnn nnnn / nn
 nnn nnn nnn.\n>>\n>> Nnnn nnnnnnn\,\n>>\n>> Nnnnn Nnnnnnnn | Nnnnnnnnnn Nn
 nnnnnn Nnnnn Nnnnnn\n>>\n>> NNN Nnnnnn Nnnnnnn\n>> Nnnn Nnnnn Nnnnn\,\n>> 
 99 Nnnnnnnnnn Nnnnnn\,\n>> Nnnnnn\, NN9N 9NN\n>> +999999999999 | Nnnn: nnn
 nnnnnn@nnn.nnn\n>> nnnnnnnnn@nnn.nnn | nnn.nnn.nnn\n>>\n>> -----Nnnnnnnn N
 nnnnnn-----\n>> Nnnn: Nnnnn N. Nnnnnnnnnnn [nnnnnn:nnn@nnnnnnnn.nn]\n>> Nn
 nn: 99 Nnnnnn 9999 9:99 NN\n>> Nn: NNN Nnnnnn <NNNNnnnnn@nnn.nnn>\n>> Nn: 
 Nnnn Nnnnn <nnnnnn@nnn.nnn>\; Nnnn Nnnnnnnn <nnnnnnnnn@nnn.nnn>\;\n>> +NNN
 N <NNNN@nnn.nnn>\; +NN Nnnnnn <Nnnnnnnn@nnn.nnn>\n>> Nnnnnnn: Nn: [NNN] Nn
 : Nnnnnnn nnnnnnn nn NNN\n>>\n>> Nnnnn nnnnn.\n>>\n>> N nnnn nnn nnnnnn nn
 nn nnnn\, nnn N'n nnnnnn nnnnn nnnn nnnnnn nn nn\n>> nnn.  N nnnnn nn nnn 
 nnnnn nnnnn nn nnn nnnnn nnnnnnnnn nnnn-nnn-nnnn\n>> nnn nnnn-nn-nnnn nnnn
 nn.  Nnn nn nnnnnnn nn nnn nnnnn nnnnn nnnnn?\n>> Nnn nnnn-nnn-nnnn\, nnn 
 nnnnnnnn nnnnnn nnnnnnn nn n nnnnnn\, nnnnn N\n>> nnn nnnnnnnnn n nnnnnn. 
  Nn nnnn nnnnnnn nn nnn nnn nnnnnnnnnn nnn\n>> nnnn nnnn nn nnnnn\, nn nnn
 nnnn nnnn nn nnn nnnn nnnnnn nnnnn?\n>>\n>> Nnnnnn nnn nn nnnn nn nn\, nn 
 nnnn nnnnnnnn nnn nnnn nnnnn nnnnn nn\n>> nnnnnn nn nnnnnnnnnn nnn nnn nnn
 nnnnnnn nnnnnn nnnn nn nnn nnnnn\n>> nnnn\, nnn nn nnnnn nn nnnn nn nnnn n
 nn nnnnnnn nnn nnnnnnnnnn.\n>>\n>> N nnnn nnnnnnnnnnnn nnnnnn nnnnnn nnnnn
 n\, nnnnn nnnnnn\, nnnnnnnnn\n>> nnnnn nnnnnnn nnn nnnnnn nnnnnnn\, NNN nn
 nnnn\, nnnnnnnnn nnnnnnnn\n>> nnnnnnnnnn\, nnn nnnnn nnnnnnnnnnnnn.\n>>\n>
 > Nnn nn nn nnnnnnn nn nnnnnnnnnn?  Nn nn nnnn nn nnnn nnnn nnnnnn nnnn nn
 nnnnnnn nn nnn?\n>>\n>> --\n>> Nnn/Nnnnnnn\n>> Nnnnn N. Nnnnnnnnnnn\n>> Nn
 nnnnnn Nnnn NN\n>>\n>> Nn Nnn\, Nnn 99 9999 nn 99:99\, NNN Nnnnnn nnnnn:\n
 >>\n>>> Nn Nnnnn\,\n>>>\n>>> Nnnnn - N nnnn nnnn nnnn nnnnn nnnnnnnnnn nn 
 nnn nnn nnnnnn nn nnn nnn nnnnnnnnnnn.\n>>>\n>>> Nnnnnn nnnnnnnn nnnnnnn.\
 n>>>\n>>> Nnnn nnnnnnn\,\n>>>\n>>> Nnnnn Nnnnnnnn | Nnnnnnnnnn Nnnnnnnn Nn
 nnn Nnnnnn\n>>>\n>>> NNN Nnnnnn Nnnnnnn\n>>> Nnnn Nnnnn Nnnnn\,\n>>> 99 Nn
 nnnnnnnn Nnnnnn\,\n>>> Nnnnnn\, NN9N 9NN\n>>> +999999999999 | Nnnn: nnnnnn
 nnn@nnn.nnn\n>>> nnnnnnnnn@nnn.nnn | nnn.nnn.nnn\n>>>\n>>> -----Nnnnnnnn N
 nnnnnn-----\n>>> Nnnn: Nnnnn N. Nnnnnnnnnnn [nnnnnn:nnn@nnnnnnnn.nn]\n>>> 
 Nnnn: 99 Nnnn 9999 9:99 NN\n>>> Nn: NNN Nnnnnn <NNNNnnnnn@nnn.nnn>\n>>> Nn
 : Nnnn Nnnnn <nnnnnn@nnn.nnn>\; Nnnn Nnnnnnnn <nnnnnnnnn@nnn.nnn>\;\n>>> +
 NNNN <NNNN@nnn.nnn>\; +NN Nnnnnn <Nnnnnnnn@nnn.nnn>\n>>> Nnnnnnn: Nn: [NNN
 ] Nn: Nnnnnnn nnnnnnn nn NNN\n>>>\n>>> Nn\, Nnnnn\n>>>\n>>> Nn nnnn nnnnnn
 nnn nnnn nnnn NN nnnn.  Nnnnn nnn nnnn n nnn nnnnn\n>>> nnnn nnnnn nnnnnnn
 n NN nnnn nnnnnnn nnn nn nnnn\, nn nn nnnnn nn nnnn\n>>> nn nnnn nnnn nnnn
 nn nnnn\, nnn nn'n nnn n nnnnnnnn.\n>>>\n>>> N nnn'n nnnnnnnn nnnn nn nnn 
 nnnn nnnnnnn nnn nnn nn nnnn\, nnn nnnnnnnnnn nn nnn nnnnn nnn nnnn NNN nn
 nnnnnnnnnnn nn nn nnn nnnnn nnn.\n>>>\n>>> --\n>>> Nnn/Nnnnnnn\n>>> Nnnnn 
 N. Nnnnnnnnnnn\n>>> Nnnnnnnn Nnnn NN\n>>>\n>>> Nn Nnn\, Nnn 99 9999 nn 99:
 99\, NNN Nnnnnn nnnnn:\n>>>\n>>>> Nn Nnnnn\,\n>>>>\n>>>> Nnnn nnn'nn nnn n
  nnnn nnnnnnn.\n>>>>\n>>>> Nn nn nn nnnnnnn nnnnnnnnn\, nnnnn N nnn nnnnnn
 n nn nnnn nnnnnn\n>>>> nnnnnnn. Nnn N nnnnnnn nnnnnnn nnn nnnn nn nnnnnnn 
 NN nnn NN nnnn\,\n>>>> nn nnn nn nnn nnnnn?\n>>>>\n>>>> Nnnnn nn nnnn nnnn
 nn\, N nnnn nn nnnnn nnn nnnn nnnnn nnnn nnnnnnnnn nn nnnn nnn nnnnnnnn NN
 N nnnnnnnnn nnn nn nnn nn nnnn nnnnn.\n>>>>\n>>>> Nnnn nnnnnnn\,\n>>>>\n>>
 >> Nnnnn Nnnnnnnn | Nnnnnnnnnn Nnnnnnnn Nnnnn Nnnnnn\n>>>>\n>>>> NNN Nnnnn
 n Nnnnnnn\n>>>> Nnnn Nnnnn Nnnnn\,\n>>>> 99 Nnnnnnnnnn Nnnnnn\,\n>>>> Nnnn
 nn\, NN9N 9NN\n>>>> +999999999999 | Nnnn: nnnnnnnnn@nnn.nnn\n>>>> nnnnnnnn
 n@nnn.nnn | nnn.nnn.nnn\n>>>>\n>>>> -----Nnnnnnnn Nnnnnnn-----\n>>>> Nnnn:
  Nnnnn N. Nnnnnnnnnnn [nnnnnn:nnn@nnnnnnnn.nn]\n>>>> Nnnn: 99 Nnnn 9999 9:
 99 NN\n>>>> Nn: NNN Nnnnnn <NNNNnnnnn@nnn.nnn>\n>>>> Nn: Nnnn Nnnnn <nnnnn
 n@nnn.nnn>\; Nnnn Nnnnnnnn <nnnnnnnnn@nnn.nnn>\;\n>>>> +NNNN <NNNN@nnn.nnn
 >\; +NN Nnnnnn <Nnnnnnnn@nnn.nnn>\n>>>> Nnnnnnn: Nn: [NNN] Nn: Nnnnnnn nnn
 nnnn nn NNN\n>>>>\n>>>> Nn\, Nnnnn.\n>>>>\n>>>> Nnnn nnnn nnnnnnnnn :)\n>>
 >>\n>>>> Nn nnn nnnnnn nnnnnnnnn-nn-nnnnnn nnn/nn nnnn-nnn-nnnn nnnnnn?  N
 \n>>>> nnnnn nnnn nn nnnn\, nnn nnn n nnnnnn nnnnnnnn nnnnn nnn nnnnnnnnn 
 -\n>>>> nnnn nnnn nnnnnnnn nnnnnnn nnn nnnnn nnnn nnn nnnnnnnnnnnn\, nn\n>
 >>> nnnnnnn nnnn nnnnn nnn nn nnnnnn?\n>>>>\n>>>> --\n>>>> Nnn/Nnnnnnn\n>>
 >> Nnnnn N. Nnnnnnnnnnn\n>>>> Nnnnnnnn Nnnn NN\n>>>>\n>>>> Nn Nnn\, Nnn 99
  9999 nn 99:99\, NNN Nnnnnn nnnnn:\n>>>>\n>>>>> Nn Nnnnn\,\n>>>>>\n>>>>> N
 nnnnn nnn nnnn nnnnn. N nnnnnn nnnn nn nnnnnn nn nnnnnnnn nn nnn nnnn nnnn
 nnnnnnn nn nnn nnnnnn nn.\n>>>>>\n>>>>> Nnn nn nnnnn nnnn Nnn\, nnn nn nnn
  nnnnn nn nn Nnnnnn.\n>>>>>\n>>>>> Nnnn n nnnnn nnnnnnn.\n>>>>>\n>>>>> Nnn
 nn Nnnnnnnn | Nnnnnnnnnn Nnnnnnnn Nnnnn Nnnnnn\n>>>>>\n>>>>> NNN Nnnnnn Nn
 nnnnn\n>>>>> Nnnn Nnnnn Nnnnn\,\n>>>>> 99 Nnnnnnnnnn Nnnnnn\,\n>>>>> Nnnnn
 n\, NN9N 9NN\n>>>>> +999999999999 | Nnnn: nnnnnnnnn@nnn.nnn\n>>>>> nnnnnnn
 nn@nnn.nnn | nnn.nnn.nnn\n>>>>>\n>>>>> Nnnnn\n>>>>>\n>>>>> -----Nnnnnnnn N
 nnnnnn-----\n>>>>> Nnnn: Nnnnn N. Nnnnnnnnnnn [nnnnnn:nnn@nnnnnnnn.nn]\n>>
 >>> Nnnn: 99 Nnnn 9999 9:99 NN\n>>>>> Nn: NNN Nnnnnn <NNNNnnnnn@nnn.nnn>\n
 >>>>> Nn: Nnnn Nnnnn <nnnnnn@nnn.nnn>\; Nnnn Nnnnnnnn\n>>>>> <nnnnnnnnn@nn
 n.nnn>\;\n>>>>> +NNNN <NNNN@nnn.nnn>\; +NN Nnnnnn <Nnnnnnnn@nnn.nnn>\n>>>>
 > Nnnnnnn: Nn: [NNN] Nn: Nnnnnnn nnnnnnn nn NNN\n>>>>>\n>>>>> Nn\, Nnnnn.\
 n>>>>>\n>>>>> Nn nnnnnn nnnnn nnn nnn nnn nn 9999 NN.  N nnnnnnnn nnn nnn\
 n>>>>> nnnnnnnn nnnnnnn nnnnn\, nnn nnn nnnnnn nn nnn nnnnnnnnn nnnnnn\n>>
 >>> nnnnnnn.  Nn nnn\n>>>>> NnnNnn(99) nnn nn 9.  Nnnnn nnnn nn nnnnn nnn 
 nnnn nnnnn nnnn nnn\n>>>>> nnnnnnn nnnnnnnn nnnnn\, N nnnnn nnnnnn NnnNnn 
 nn nnnnnn nn 9999\,\n>>>>> nn nn nnn nn nnn nnnnnnnn nnnnnnn.\n>>>>>\n>>>>
 > Nn nnnn nn nnnnnnnn nn nnn nnnnnnn nnnnnnnnnnn\, nn nnnn nnnn nnnnnnnnn 
 nn nnn nnnn nn nnnnnnnnnn?\n>>>>>\n>>>>> (Nnnn n nnnn nnnnnnn\, N'n nnnnnn
 n nnn nnn\, nnnn nnnnnnnn nnnn nn\n>>>>> nnnnnn.)\n>>>>> --\n>>>>> Nnn/Nnn
 nnnn\n>>>>> Nnnnn N. Nnnnnnnnnnn\n>>>>> Nnnnnnnn Nnnn NN\n>>>>>\n>>>>> Nn 
 Nnn\, Nnn 99 9999 nn 99:99\, NNN Nnnnnn nnnnn:\n>>>>>\n>>>>>> Nn Nnnnn\,\n
 >>>>>>\n>>>>>> N nnn nnn nnnnn nnnnnnnn. N nnnn nnnnnnnnn nnnn nnn nnnnnnn
 nnnn nnnn nnnn nn nnnn nnn nnnnnnnnn nnnnnnnnn nnnnnnnnnn nn nnnnn nnn nnn
 nnnnnn nnnnnnn:\n>>>>>>\n>>>>>> 9 nn 99 === nnnnnnnn\n>>>>>> 999 nn 999 ==
 = nnnn nnnnnnnn\n>>>>>> 999 nn 9999 === nnnnnnn nnnnnnn 999 nnn nnnn nnnnn
 nn\n>>>>>> 9999 nn 9999 === nnnnnnn nnnnnnn 999 nnn nnnnnn nnnnnnn\n>>>>>>
  9999 nn 9999 === nnnnnnn nnnnnnn 999\, 999 \, 999 \, 999 nnn nnnn\n>>>>>>
  nnnnnnn\n>>>>>> 9999 nn 9999 === nnnnnnn nnnnnnn 999\, 999\, 999\, 999 nn
 n nnnnnn\n>>>>>> nnnnnnn Nnnn 9999 === nnnnn nnnnn.\n>>>>>>\n>>>>>> Nn nnn
  nnnnn nnnn nn nnnnnn nnn nnnnnnnn nn nnnnn nnn nnnnnnnnnn nnnnn nnn nnnnn
 n nnn nnn nnnnnnnnn nnnnnnnnn nn nnnnnnnnn.\n>>>>>>\n>>>>>> Nnnn nnnnnnn\,
 \n>>>>>>\n>>>>>> Nnnnn Nnnnnnnn | Nnnnnnnnnn Nnnnnnnn Nnnnn Nnnnnn\n>>>>>>
 \n>>>>>> NNN Nnnnnn Nnnnnnn\n>>>>>> Nnnn Nnnnn Nnnnn\,\n>>>>>> 99 Nnnnnnnn
 nn Nnnnnn\,\n>>>>>> Nnnnnn\, NN9N 9NN\n>>>>>> +999999999999 | Nnnn: nnnnnn
 nnn@nnn.nnn\n>>>>>> nnnnnnnnn@nnn.nnn | nnn.nnn.nnn\n>>>>>>\n>>>>>> -----N
 nnnnnnn Nnnnnnn-----\n>>>>>> Nnnn: Nnnnn N. Nnnnnnnnnnn [nnnnnn:nnn@nnnnnn
 nn.nn]\n>>>>>> Nnnn: 99 Nnnn 9999 9:99 NN\n>>>>>> Nn: NNN Nnnnnn <NNNNnnnn
 n@nnn.nnn>\n>>>>>> Nn: Nnnn Nnnnn <nnnnnn@nnn.nnn>\; Nnnn Nnnnnnnn\n>>>>>>
  <nnnnnnnnn@nnn.nnn>\;\n>>>>>> +NNNN <NNNN@nnn.nnn>\; +NN Nnnnnn <Nnnnnnnn
 @nnn.nnn>\n>>>>>> Nnnnnnn: Nn: [NNN] Nn: Nnnnnnn nnnnnnn nn NNN\n>>>>>>\n>
 >>>>> Nnnnn nnnnn\, Nnnnn.\n>>>>>>\n>>>>>> N nnnn nnnnn nnnnnnnn n nnnn nn
 nnn nnn nnn nn 99 Nnnn Nnnn.  Nnn\n>>>>>> nnnnn nnn nnnnnnnn nnnn nnn nnnn
  "NnnnnNnnnnn Nnnnnn : NNNNNN\n>>>>>> NNNN nnn nnnnnn nn nnn<".  Nnn nn nn
 nn?\n>>>>>>\n>>>>>> --\n>>>>>> Nnn/Nnnnnnn\n>>>>>> Nnnnn N. Nnnnnnnnnnn\n>
 >>>>> Nnnnnnnn Nnnn NN\n>>>>>>\n>>>>>> Nn Nnn\, Nnn 99 9999 nn 99:99\, NNN
  Nnnnnn nnnnn:\n>>>>>>\n>>>>>>> Nn Nnnnn\,\n>>>>>>>\n>>>>>>> Nnnn nnn nnn 
 n nnnn nnnn nnn. Nnnn nn nnnn nn nn nnn nnnnnnn nnnnnnn nnnnnnNnnNN.\n>>>>
 >>>\n>>>>>>> Nnnnnn nnn nn nnnn nn N nnn nnnnnn nnnnnn nnnnnnn.\n>>>>>>>\n
 >>>>>>> Nnnn nnnnnnn\,\n>>>>>>>\n>>>>>>> Nnnnn Nnnnnnnn | Nnnnnnnnnn Nnnnn
 nnn Nnnnn Nnnnnn\n>>>>>>>\n>>>>>>> NNN Nnnnnn Nnnnnnn\n>>>>>>> Nnnn Nnnnn 
 Nnnnn\,\n>>>>>>> 99 Nnnnnnnnnn Nnnnnn\,\n>>>>>>> Nnnnnn\, NN9N 9NN\n>>>>>>
 > +999999999999 | Nnnn: nnnnnnnnn@nnn.nnn\n>>>>>>> nnnnnnnnn@nnn.nnn | nnn
 .nnn.nnn\n>>>>>>>\n>>>>>>> -----Nnnnnnnn Nnnnnnn-----\n>>>>>>> Nnnn: Nnnnn
  N. Nnnnnnnnnnn [nnnnnn:nnn@nnnnnnnn.nn]\n>>>>>>> Nnnn: 99 Nnnn 9999 9:99 
 NN\n>>>>>>> Nn: NNN Nnnnnn <NNNNnnnnn@nnn.nnn>\n>>>>>>> Nn: Nnnn Nnnnn <nn
 nnnn@nnn.nnn>\; Nnnn Nnnnnnnn\n>>>>>>> <nnnnnnnnn@nnn.nnn>\;\n>>>>>>> +NNN
 N <NNNN@nnn.nnn>\; +NN Nnnnnn <Nnnnnnnn@nnn.nnn>\n>>>>>>> Nnnnnnn: Nn: [NN
 N] Nn: Nnnnnnn nnnnnnn nn NNN\n>>>>>>>\n>>>>>>> Nn.\n>>>>>>>\n>>>>>>> N'nn
  nnnn nn nnnnnnn nnn n nnnnnn nn nnnnn.\n>>>>>>>\n>>>>>>> N'n nnnnnnnnn nn
 nnnnnnnnnn nnnnnn nn nn nnn NNN nnnnnn.  Nnn nnnnn nnn\, nn N nnnnnnnnn\, 
 nn nnn nnnn nnn nnnnnnNnnNN nn nnnnn.\n>>>>>>>\n>>>>>>> N nnnn nnnnn nnnnn
 nn nnnnnn nnnnnnn.\n>>>>>>>\n>>>>>>> --\n>>>>>>> Nnn/Nnnnnnn\n>>>>>>> Nnnn
 n N. Nnnnnnnnnnn\n>>>>>>> Nnnnnnnn Nnnn NN\n>>>>>>>\n>>>>>>> Nn Nnn\, Nnn 
 99 9999 nn 99:99\, NNN Nnnnnn nnnnn:\n>>>>>>>\n>>>>>>>> Nn Nnnnn\,\n>>>>>>
 >>\n>>>>>>>> Nnnnn nnn nnnnnnn nn nnnnn nnnnn nnn nn nnnnnn.\n>>>>>>>>\n>>
 >>>>>> Nnnn nnnnnnn\,\n>>>>>>>>\n>>>>>>>> Nnnnn Nnnnnnnn | Nnnnnnnnnn Nnnn
 nnnn Nnnnn Nnnnnn\n>>>>>>>>\n>>>>>>>> NNN Nnnnnn Nnnnnnn\n>>>>>>>> Nnnn Nn
 nnn Nnnnn\,\n>>>>>>>> 99 Nnnnnnnnnn Nnnnnn\,\n>>>>>>>> Nnnnnn\, NN9N 9NN\n
 >>>>>>>> +999999999999 | Nnnn: nnnnnnnnn@nnn.nnn\n>>>>>>>> nnnnnnnnn@nnn.n
 nn | nnn.nnn.nnn\n>>>>>>>>\n>>>>>>>> -----Nnnnnnnn Nnnnnnn-----\n>>>>>>>> 
 Nnnn: Nnnnn N. Nnnnnnnnnnn [nnnnnn:nnn@nnnnnnnn.nn]\n>>>>>>>> Nnnn: 99 Nnn
 n 9999 9:99 NN\n>>>>>>>> Nn: NNN Nnnnnn <NNNNnnnnn@nnn.nnn>\n>>>>>>>> Nn: 
 Nnnn Nnnnn <nnnnnn@nnn.nnn>\; Nnnn Nnnnnnnn\n>>>>>>>> <nnnnnnnnn@nnn.nnn>\
 ;\n>>>>>>>> +NNNN <NNNN@nnn.nnn>\; +NN Nnnnnn <Nnnnnnnn@nnn.nnn>\n>>>>>>>>
  Nnnnnnn: Nn: [NNN] Nn: Nnnnnnn nnnnnnn nn NNN\n>>>>>>>>\n>>>>>>>> Nn nnnn
 n.\n>>>>>>>>\n>>>>>>>> N nnnn nnnnnnnnnnnn\, nnn nn nnnnnnnnn nnnnn nnnn n
 nn nnnnnn.\n>>>>>>>> Nn nnnnnnn nn nn nnnn nn nn nnn nnnnnn nnn nnnnnnnnnn
  nnnnnnnn\n>>>>>>>> nn nnnnnnnnn nn nnnnn nnnnnnn.  Nn nnnn nnnn nnnn nn n
 nnnnnnnnn\n>>>>>>>> nn nn nnn?\n>>>>>>>>\n>>>>>>>> N nnnnnn nn nn 999.999.
 99.999:9999 nn nnnnnnnnnnnnn 99:99 NNN\,\n>>>>>>>> nnnn nnnnNnn NNNN/NNN n
 nn nnnnnnNnnNn NNNN.  Nn nnnnnnn nnn\n>>>>>>>> nnnnnnNnnNn nnnn nn nn nnnn
  nn nnn nnnnn nnnnnnnn nnnnnnnn?\n>>>>>>>>\n>>>>>>>> --\n>>>>>>>> Nnn/Nnnn
 nnn\n>>>>>>>> Nnnnn N. Nnnnnnnnnnn\n>>>>>>>> Nnnnnnnn Nnnn NN\n>>>>>>>>\n>
 >>>>>>> Nn Nnn\, Nnn 99 9999 nn 99:99\, Nnnnn N. Nnnnnnnnnnn nnnnn:\n>>>>>
 >>>\n>>>>>>>>> Nn\, Nnnnn.\n>>>>>>>>>\n>>>>>>>>> Nnnnn nnn\, N'nn nnn nn n
 n nnn nnn nnnnn nnnnnnn\, nnnnnn nnnnnnnn.\n>>>>>>>>>\n>>>>>>>>> --\n>>>>>
 >>>> Nnn/Nnnnnnn\n>>>>>>>>> Nnnnn N. Nnnnnnnnnnn\n>>>>>>>>> Nnnnnnnn Nnnn 
 NN\n>>>>>>>>>\n>>>>>>>>> Nn Nnn\, Nnn 99 9999 nn 99:99\, NNN Nnnnnn nnnnn:
 \n>>>>>>>>>\n>>>>>>>>>> Nn Nnnnn\,\n>>>>>>>>>>\n>>>>>>>>>> N'nn nnnn nnnnn
 nn nnn NN nnn nnnnnn nnn nnnnnnn. Nnnnnn\n>>>>>>>>>> nnnnnn 999.999.99.999
 . (Nnnn 9999)\n>>>>>>>>>>\n>>>>>>>>>> Nnnn nnnnnnn\,\n>>>>>>>>>>\n>>>>>>>>
 >> Nnnnn Nnnnnnnn | Nnnnnnnnnn Nnnnnnnn Nnnnn Nnnnnn\n>>>>>>>>>>\n>>>>>>>>
 >> NNN Nnnnnn Nnnnnnn\n>>>>>>>>>> Nnnn Nnnnn Nnnnn\,\n>>>>>>>>>> 99 Nnnnnn
 nnnn Nnnnnn\,\n>>>>>>>>>> Nnnnnn\, NN9N 9NN\n>>>>>>>>>> +999999999999 | Nn
 nn: nnnnnnnnn@nnn.nnn\n>>>>>>>>>> nnnnnnnnn@nnn.nnn | nnn.nnn.nnn\n>>>>>>>
 >>>\n>>>>>>>>>> -----Nnnnnnnn Nnnnnnn-----\n>>>>>>>>>> Nnnn: Nnnnn N. Nnnn
 nnnnnnn [nnnnnn:nnn@nnnnnnnn.nn]\n>>>>>>>>>> Nnnn: 99 Nnnn 9999 99:99 NN\n
 >>>>>>>>>> Nn: Nnnn Nnnnn <nnnnnn@nnn.nnn>\n>>>>>>>>>> Nn: NNN Nnnnnn <NNN
 Nnnnnn@nnn.nnn>\; Nnnn Nnnnnnnn\n>>>>>>>>>> <nnnnnnnnn@nnn.nnn>\; +NNNN <N
 NNN@nnn.nnn>\; +NN Nnnnnn\n>>>>>>>>>> <Nnnnnnnn@nnn.nnn>\n>>>>>>>>>> Nnnnn
 nn: Nn: [NNN] Nn: Nnnnnnn nnnnnnn nn NNN\n>>>>>>>>>>\n>>>>>>>>>> Nnnnnnnnn
 n\, nnnn nn nnnnnnn nnnn nn nnnnn nnnn nnn.  Nnnnnn!\n>>>>>>>>>> --\n>>>>>
 >>>>> Nnn/Nnnnnnn\n>>>>>>>>>> Nnnnn N. Nnnnnnnnnnn\n>>>>>>>>>> Nnnnnnnn Nn
 nn NN\n>>>>>>>>>>\n>>>>>>>>>> Nn Nnn\, Nnn 99 9999 nn 99:99\, Nnnn Nnnnn n
 nnnn:\n>>>>>>>>>>\n>>>>>>>>>>> Nnn\, n nnnnnnnnn nnnnnn nnnn nnnnnn nn nnn
  nnnnnnnnnnnn nn nnn nnnnn nnnnnnnnnn nn nnn nnnnnn nnnn. Nn nnnn nnn nnn'
 n nnnnnn nn nn nnnnnn?\n>>>>>>>>>>>\n>>>>>>>>>>> Nnnnnnn\,\n>>>>>>>>>>>\n>
 >>>>>>>>>> Nnnn Nnnnn\n>>>>>>>>>>>\n>>>>>>>>>>> N: +99 (9)99 9999 9999 | N
 : +99 (9)99 9999 9999\n>>>>>>>>>>>\n>>>>>>>>>>> -----Nnnnnnnn Nnnnnnn-----
 \n>>>>>>>>>>> Nnnn: Nnnnn N. Nnnnnnnnnnn [nnnnnn:nnn@nnnnnnnn.nn]\n>>>>>>>
 >>>> Nnnn: Nnnnnnnn\, Nnnn 9\, 9999 99:99 NN\n>>>>>>>>>>> Nn: Nnnn Nnnnn\n
 >>>>>>>>>>> Nn: NNN Nnnnnn\; Nnnn Nnnnnnnn\; +NNNN\; +NN Nnnnnn\n>>>>>>>>>
 >> Nnnnnnn: Nn: [NNN] Nn: Nnnnnnn nnnnnnn nn NNN\n>>>>>>>>>>>\n>>>>>>>>>>>
  Nn\, Nnnn.\n>>>>>>>>>>>\n>>>>>>>>>>> Nnnnnnnnnnnn nnnnnn nnnnnn nn nnnn n
 n nnnnnn@nnnnnnnn.nn\, nnnnn nn n nnnnnnnnnnnn nnnn nnn nnnnn nnnn nnn.\n>
 >>>>>>>>>>\n>>>>>>>>>>> Nnnn nnn nnnn nnnnnn NNN nnnnnn nnnn nnnnnnnn nnnn
 nnnnn nnnn n nnnnnnnnn nnnnnn?\n>>>>>>>>>>>\n>>>>>>>>>>> --\n>>>>>>>>>>> N
 nn/Nnnnnnn\n>>>>>>>>>>> Nnnnn N. Nnnnnnnnnnn\n>>>>>>>>>>> Nnnnnnnn Nnnn NN
 \n>>>>>>>>>>>\n>>>>>>>>>>> Nn Nnn\, Nnn 99 9999 nn 99:99\, Nnnn Nnnnn nnnn
 n:\n>>>>>>>>>>>\n>>>>>>>>>>>> Nn Nnnnn\,\n>>>>>>>>>>>>\n>>>>>>>>>>>> Nn NN
 N nnnnnn\, N nnn nnnnnnn nnnn nn nnnn nnnnnn nnnn nnnn\n>>>>>>>>>>>> nnnnn
  nn n nnnnnnnnn nnnnnn. Nnn nnnnnnnnnnnn nnnn nn\n>>>>>>>>>>>> nnnnnnnnnnn
  nn nn nnnnn nnnnnnnnnnnn\, nnnnnn nnn nn nnnn\n>>>>>>>>>>>> nnn nnnnnn nn
  nnn nnnnnnnnnn nn nnnn nnnnn.\n>>>>>>>>>>>>\n>>>>>>>>>>>> Nnn nnnnnnn nnn
 nnnnn nn NNN/NNN nnnnnn nn nnn nnnn nnnn nnnn nn nnnnn.\n>>>>>>>>>>>>\n>>>
 >>>>>>>>> Nnnnnnn\,\n>>>>>>>>>>>>\n>>>>>>>>>>>> Nnnn Nnnnn\n>>>>>>>>>>>>\n
 >>>>>>>>>>>> N: +99 (9)99 9999 9999 | N: +99 (9)99 9999 9999\n>>>>>>>>>>>>
 \n>>>>>>>>>>>> -----Nnnnnnnn Nnnnnnn-----\n>>>>>>>>>>>> Nnnn: Nnnnn N. Nnn
 nnnnnnnn [nnnnnn:nnn@nnnnnnnn.nn]\n>>>>>>>>>>>> Nnnn: Nnnnnnnn\, Nnnn 9\, 
 9999 99:99 NN\n>>>>>>>>>>>> Nn: NNN Nnnnnn\n>>>>>>>>>>>> Nn: Nnnn Nnnnnnnn
 \; +NNNN\; +NN Nnnnnn\n>>>>>>>>>>>> Nnnnnnn: Nn: [NNN] Nn: Nnnnnnn nnnnnnn
  nn NNN\n>>>>>>>>>>>>\n>>>>>>>>>>>> Nn\, Nnnnn.\n>>>>>>>>>>>>\n>>>>>>>>>>>
 > Nn nnnnnnnnnnn nnnn nnnnnnnnn nnnn nnnn.nnnnnnnn.nn\, 99.99.999.99.\n>>>
 >>>>>>>>>\n>>>>>>>>>>>> --\n>>>>>>>>>>>> Nnn/Nnnnnnn\n>>>>>>>>>>>> Nnnnn N
 . Nnnnnnnnnnn\n>>>>>>>>>>>> Nnnnnnnn Nnnn NN\n>>>>>>>>>>>>\n>>>>>>>>>>>> N
 n Nnn\, Nnn 99 9999 nn 99:99\, NNN Nnnnnn nnnnn:\n>>>>>>>>>>>>\n>>>>>>>>>>
 >>> Nn Nnnnn\,\n>>>>>>>>>>>>>\n>>>>>>>>>>>>> N nnnn nnnnnnnn nnn nnnnnnn n
 nnn nn nnnn nnnnnn nnn nn nnnn nnnnnnnnn nnnnn N nnnn nnnnnnnnnnn nn nnn:\
 n>>>>>>>>>>>>>\n>>>>>>>>>>>>> Nn nnnnn n nnnnnnn nnnnnnn nnn NNN/NNN nnnnn
 n nn nnnn nnnnnn?  Nnn nn nnnn nnnnnn nnnnnnnnnnnnn nnnnnnnnn nn nnnn nn n
 nnnnnnnn nnnnnnn?\n>>>>>>>>>>>>>\n>>>>>>>>>>>>> Nnnnnn nnnn nn nnnnnnn nnn
 nn:\n>>>>>>>>>>>>>\n>>>>>>>>>>>>> Nn nnnnn nnnnnn nnn nn nnnnnn NN 999.99.
 999.99 nnnn nnn\n>>>>>>>>>>>>> nnnnnnnn nnn nnnn NNN nnnnnnn. Nnnnn nnn nn
 nnnn nnnnnn nnnn NN nnn nnnn nn nnnnnnnnnn nnnn nn nn nnn nnnnnnnnnn nnn n
 n nnn nnnnnnnn?\n>>>>>>>>>>>>>\n>>>>>>>>>>>>> Nnn nnnn NNN nnnnnnn nn nnnn
 nn 9.9. Nnn99 nn nnn nnnnnnnnn\n>>>>>>>>>>>>> nnn nn nnnnnnnnn nn nnnn nn 
 nn nnnnnnnn. Nnn9999 nn nnnnnnnnn nnn nnn nnnnnnnnnn\, nnnnnnn\, nn nnn nn
 nnnnn nn nnnn nnnnnn 9999=NNN.\n>>>>>>>>>>>>>\n>>>>>>>>>>>>> Nn nn nnnnnnn
 n nn nnnnnnnn nnnnnnnnnn nnn NNN nn Nnn nn nnn nn nnn nnnnnnn nn nnn nnnnn
 .\n>>>>>>>>>>>>>\n>>>>>>>>>>>>> Nnnnn nnn9 nnn nnnnnnnnnn nnnn nn nnnn nn 
 nnn nnn nnnnnn\n>>>>>>>>>>>>>\n>>>>>>>>>>>>> Nnnn nnnnnnn\,\n>>>>>>>>>>>>>
 \n>>>>>>>>>>>>> Nnnnn Nnnnnnnn | Nnnnnnnnnn Nnnnnnnn Nnnnn Nnnnnn\n>>>>>>>
 >>>>>>\n>>>>>>>>>>>>> NNN Nnnnnn Nnnnnnn\n>>>>>>>>>>>>>\n>>>>>>>>>>>>> Nnn
 n Nnnnn Nnnnn\,\n>>>>>>>>>>>>>\n>>>>>>>>>>>>> 99 Nnnnnnnnnn Nnnnnn\,\n>>>>
 >>>>>>>>>\n>>>>>>>>>>>>> Nnnnnn\, NN9N 9NN\n>>>>>>>>>>>>>\n>>>>>>>>>>>>> +
 999999999999 | Nnnn: nnnnnnnnn@nnn.nnn\n>>>>>>>>>>>>>\n>>>>>>>>>>>>> nnnnn
 nnnn@nnn.nnn | nnn.nnn.nnn\n>>>>>>>>>>>>>\n>>>>>>>>>>>>> -----Nnnnnnnn Nnn
 nnnn-----\n>>>>>>>>>>>>>\n>>>>>>>>>>>>> Nnnn: Nnnnn N. Nnnnnnnnnnn [nnnnnn
 :nnn@nnnnnnnn.nn]\n>>>>>>>>>>>>>\n>>>>>>>>>>>>> Nnnn: 99 Nnnn 9999 9:99 NN
 \n>>>>>>>>>>>>>\n>>>>>>>>>>>>> Nn: Nnnnn Nnnnnnnn <nnnnnnnnn@nnn.nnn>\n>>>
 >>>>>>>>>>\n>>>>>>>>>>>>> Nn: NNN Nnnnnn <NNNNnnnnn@nnn.nnn>\; Nnnn Nnnnnn
 nn\n>>>>>>>>>>>>> <nnnnnnnnn@nnn.nnn>\;\n>>>>>>>>>>>>> +NNNN <NNNN@nnn.nnn
 >\n>>>>>>>>>>>>>\n>>>>>>>>>>>>> Nnnnnnn: [NNN] Nn: Nnnnnnn nnnnnnn nn NNN\
 n>>>>>>>>>>>>>\n>>>>>>>>>>>>> Nn nnnnn.\n>>>>>>>>>>>>>\n>>>>>>>>>>>>> Nnnn
  n nnnnnnnnn nnnnn nn nnnn nnnn nnnnn nnnnnnnnnnnnnnn\, N nnnnn.\n>>>>>>>>
 >>>>> Nn nn nnnn nn nnnnnnn 99=NNNN\;9999=NNN\, nn nn nnn nnnnnnn nn n Nnn
 nnnNnnNN nnn Nnnnnnnn nnnnn nn n NNN nnnnn?  Nnn nnn nnnn NNN nnnnnnn nn n
 nnnn 9.9\, nnnnnnn?\n>>>>>>>>>>>>>\n>>>>>>>>>>>>> Nn nnnnnnn nnn nnn nnnnn
 n nn nnn 99 nnn nnnnnnnnn\, nn nnnn nnnnnn nn nn.\n>>>>>>>>>>>>>\n>>>>>>>>
 >>>>> Nn nnn'n nnnnnnnnn nnnnnnn n NnnnNnNnnnn\, nnn nn nnnnnnnn nn n nnn 
 nnnnn.  Nnnn nn nnnnn nnnnnnn nn nnn nnnnnn nn nnn nnn nnnnnn?\n>>>>>>>>>>
 >>>\n>>>>>>>>>>>>> Nn nnn nn nnnnnnnnnn nn nnnnnnnn nn nnnnnnn nnnn nnnnn\
 ,\n>>>>>>>>>>>>> nnn nnnnnn nnn nnnnnn nn nn nnnnn NNN nnn/nn NNN nnnnnn\,
 \n>>>>>>>>>>>>> nn N nnnnnnn nn nnn nnnnnnnnn nnnnnnnnn NNN nn nnnnnnn nnn
  nnnnnn nnnn nnn\, nnn nnnnnn nn nnnn nnnnnnnn nn nnnnnnnnn nnnnnn.  Nn nn
 nnn n nnnnnnn nnnnnnn nnn NNN/NNN nnnnnn nn nnnn nnnnnn?  Nnn nn nnnn nnnn
 nn nnnnnnnnnnnnn nnnnnnnnn nn nnnn nn nnnnnnnnn nnnnnnn?\n>>>>>>>>>>>>>\n>
 >>>>>>>>>>>> Nn nnnn nnn nnn Nnnnnnn(9) nnn nnn nnnnn nn nnnnnnn nnn nnnnn
 nnnnn nnnnnnn.  Nnnn nnnn nnnnnnnn nn nnnn nn nnn nnn nnnnnn?\n>>>>>>>>>>>
 >>\n>>>>>>>>>>>>> --\n>>>>>>>>>>>>>\n>>>>>>>>>>>>> Nnn/Nnnnnnn\n>>>>>>>>>>
 >>>\n>>>>>>>>>>>>> Nnnnn N. Nnnnnnnnnnn\n>>>>>>>>>>>>>\n>>>>>>>>>>>>> Nnnn
 nnnn Nnnn NN\n>>>>>>>>>>>>>\n>>>>>>>>>>>>> Nn Nnn\, Nnn 99 9999 nn 99:99\,
  Nnnnn N. Nnnnnnnnnnn nnnnn:\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>> Nn.\n>>>>>>>>>
 >>>>\n>>>>>>>>>>>>>>\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>> Nnnnn nnnnn nnn nnnnn\
 , N nnn nnn nn nnn nnnnnn nnn nnnn\n>>>>>>>>>>>>>> nn nnnn nnnn\,\n>>>>>>>
 >>>>>>\n>>>>>>>>>>>>>> nnn nnnnn nnnn nn nnnnnnnnn nnnnnnnn nn nn nnnnn nn
 nnnnnn.\n>>>>>>>>>>>>>> N nn nnnn\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>> nnnnnnnnn
  nnn nnnnnnnnnnnnn nnn nnnn nn\, nnn nnnn nnn\n>>>>>>>>>>>>>> nnnn nn nnn 
 nnnn\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>> nnn nnnnnnnnn.\n>>>>>>>>>>>>>\n>>>>>>>
 >>>>>>>\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>> N nnnn nnn nnnnnnnnn nnnnnnnn\, nnn
 nnnnnn nnn NNN nnnnnnn\n>>>>>>>>>>>>>> nnn nnnn nnn\n>>>>>>>>>>>>>\n>>>>>>
 >>>>>>>> nn: nnnnn NN\, nnn nnn nnn nnnnnnnnn nnnnnnnnnnn nnn NNN\n>>>>>>>
 >>>>>>> nn nnnn nnn\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>> Nnnnnnnn?\n>>>>>>>>>>>>
 >\n>>>>>>>>>>>>>>\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>> --\n>>>>>>>>>>>>>\n>>>>>>
 >>>>>>>> Nnn/Nnnnnnn\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>> Nnnnn N. Nnnnnnnnnnn\n
 >>>>>>>>>>>>>\n>>>>>>>>>>>>>> Nnnnnnnn Nnnn NN\n>>>>>>>>>>>>>\n>>>>>>>>>>>
 >>>\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>> Nn Nnn\, Nnn 99 9999 nn 99:99\, Nnnnn N
 nnnnnnn nnnnn:\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>\n>>>>>>>>>>>>>\n>>>>>>>>>>>>
 >>> Nn Nnnnn\,\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>>\n>>>>>>>>>>>>>\n>>>>>>>>>>>
 >>>> Nnnnnn nnn nn nnnn nn nnnnnnnn nnnnn nn nnnnnnn\, nnn N nnnn nn nnnnn
  nn nnnnnn. Nn nnn nnnnn nnnnnn nn nnnnnnn nnnn nnn nnnnn nnnnnn nnnn nnnn
 .\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>>\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>> Nnnn nnn
 nnnn\,\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>>\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>> Nnn
 nn Nnnnnnnn | Nnnnnnnnnn Nnnnnnnn Nnnnn Nnnnnn\n>>>>>>>>>>>>>\n>>>>>>>>>>>
 >>>> [Nnnnnnnnnnn: Nnnnnnnnnnn:\n>>>>>>>>>>>>>>> nnn:nnnnn999.nnn@99NN9999
 .99999N99]\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>> NNN Nnnnnn Nnnnnnn\n>>>>>>>>>>>
 >>\n>>>>>>>>>>>>>>> Nnnn Nnnnn Nnnnn\,\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>> 99 
 Nnnnnnnnnn Nnnnnn\,\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>> Nnnnnn\, NN9N 9NN\n>>>
 >>>>>>>>>>\n>>>>>>>>>>>>>>> +999999999999 | Nnnn:\n>>>>>>>>>>>>>>> +nnnnnn
 nnn@nnn.nnn<nnnnnn:nnnnnnnnn@nnn.nnn>\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>> nnnn
 nnnnn@nnn.nnn<nnnnnn:nnnnnnnnn@nnn.nnn> |\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>> 
 nnn.nnn.nnn<nnnn://nnn.nnn.nnn/>\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>>\n>>>>>>>>
 >>>>>\n>>>>>>>>>>>>>>> Nnnn: Nnnnn Nnnnnnnn\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>
 > Nnnn: 99 Nnn 9999 99:99 NN\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>> Nn: 'nnn@nnnn
 nnnn.nn' <nnn@nnnnnnnn.nn>\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>> Nn: +NNN Nnnnnn
  <NNNNnnnnn@nnn.nnn>\; Nnnn Nnnnnnnn\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>> <nnnn
 nnnnn@nnn.nnn>\; +NNNN <NNNN@nnn.nnn>\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>> Nnnn
 nnn: Nnnnnnn nnnnnnn nn NNN\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>>\n>>>>>>>>>>>>>
 \n>>>>>>>>>>>>>>> Nn Nnnnn\,\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>>\n>>>>>>>>>>>>
 >\n>>>>>>>>>>>>>>> N nnnn nnnn nnnnn nnnn nnnnnnn nnnnnnnnnnn nn nnnnnnn n
 n nnnnnnn nnnnnnn nnnnnnn nnnnnnn nnnnnnnnnn nnn NNN.\n>>>>>>>>>>>>>\n>>>>
 >>>>>>>>>>>\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>> N nnnnnnnnnn nnnn nnn nnn nnnn
 nnn nn nnnnnn n nnnnnnnnn\n>>>>>>>>>>>>>>> NNN NNN\, nnn\n>>>>>>>>>>>>>\n>
 >>>>>>>>>>>>>> nn nnnn nnnn nn nnnn nnn nnnnnnn nnn nnnn nnn nnnnn. N\n>>>
 >>>>>>>>>>>> nnnnnnnnnn nnn\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>> nnnn nn nnnnnn
 n NNN nnnnnn nnnn. N nnnn nnnnnnnn nnn\n>>>>>>>>>>>>>>> nnnnnnn NNN\n>>>>>
 >>>>>>>>\n>>>>>>>>>>>>>>> nnnnnnnnnnnnn\, nnnnn nnn nnn nnnn nnnnnn - Nnn 
 NNN\n>>>>>>>>>>>>>>> nnnnnn nnnn nnn\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>> nnnn 
 nnnnnnnnn nn n NNN nnnnnnnn nnnnn\, nn nnnn nn nnn\n>>>>>>>>>>>>>>> NNN NN
 N nnnn\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>> nn nnn nnn NNN nnnnnn nn nn nnnnnnn
 .\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>>\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>> N nnn nn
  nnnnnnnnn nnnn n NNN nnnnnnn nnn nn nnn nnn nn nnnnn. Nn nnn nnnn nnnn nn
 nn nnnnnnn\, nn nnnnn n nnn NNN nnnnnnn nnn nnn\, nn nnn nnnnnn.\n>>>>>>>>
 >>>>>\n>>>>>>>>>>>>>>>\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>> nnnnnnNnnnNN=NNNN\n
 >>>>>>>>>>>>>\n>>>>>>>>>>>>>>> NnnnnnNnnnNN=NNN\n>>>>>>>>>>>>>\n>>>>>>>>>>
 >>>>> Nnnn=9999\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>>\n>>>>>>>>>>>>>\n>>>>>>>>>>
 >>>>> N nnnn nnnnnnn nn nnnnnnn nnnn nnn.\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>>\
 n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>> Nnnn nnnnnnn\,\n>>>>>>>>>>>>>\n>>>>>>>>>>>
 >>>>\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>> Nnnnn Nnnnnnnn | Nnnnnnnnnn Nnnnnnnn 
 Nnnnn Nnnnnn\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>> [Nnnnnnnnnnn: Nnnnnnnnnnn:\n>
 >>>>>>>>>>>>>> nnn:nnnnn999.nnn@99NN9999.99999N99]\n>>>>>>>>>>>>>\n>>>>>>>
 >>>>>>>> NNN Nnnnnn Nnnnnnn\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>> Nnnn Nnnnn Nnn
 nn\,\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>> 99 Nnnnnnnnnn Nnnnnn\,\n>>>>>>>>>>>>>
 \n>>>>>>>>>>>>>>> Nnnnnn\, NN9N 9NN\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>> +99999
 9999999 | Nnnn:\n>>>>>>>>>>>>>>> +nnnnnnnnn@nnn.nnn<nnnnnn:nnnnnnnnn@nnn.n
 nn>\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>> nnnnnnnnn@nnn.nnn<nnnnnn:nnnnnnnnn@nnn
 .nnn> |\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>> nnn.nnn.nnn<nnnn://nnn.nnn.nnn/>\n
 >>>>>>>>>>>>>\n>>>>>>>>>>>>>>>\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>> Nnnn n-nnnn
  nnn nnn nnnnnnnnnnn nnn nnnnnnnn nnnn nnn\n>>>>>>>>>>>>>>> nnn nnnnnnnnnn
 \n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>> nn nnnnnn nn nnnn nn nn nnnnnnnnn nnn nnn
  nnnnnnn\n>>>>>>>>>>>>>>> nnnnnnnnnnn nnnn nn\n>>>>>>>>>>>>>\n>>>>>>>>>>>>
 >>> nnnnnnnnnnnn\, nnnnnnnnnn\, nnnnnn nnnnnnnnnnn\, nn nnnnnnn\n>>>>>>>>>
 >>>>>> nn nnnnn\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>> nnnnnnnnnnnn nn nnn nn nnn
 nnnnnnn. Nnn nnnnnnnnnnnn nnn\,\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>> nnnnnnnnnn
 nnn nn nnnnnnn nn nnnn nnnnnnnnnnnn nn nnn\n>>>>>>>>>>>>>>> nnnnnnnnnnn nn
 \n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>> nn nn nnnnnnnnnn nnn nnn nn nnnnnnnn. Nn 
 nnn nnnn\n>>>>>>>>>>>>>>> nnnnnnnn nnnn\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>> nn
 nnnnnnnnnn nn nnnnn\, nnnnnn nnnnnn nnn nnnnnn\n>>>>>>>>>>>>>>> nnnnnnnnnn
 n nn nnnnnn\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>> n-nnnn\, nnn nnnnnnnnnnn nnnnn
 n nn nnnnnnn nnnn n-nnnn\,\n>>>>>>>>>>>>>>> nnn\n>>>>>>>>>>>>>\n>>>>>>>>>>
 >>>>> nnnnnnnnnnn\, nnn nnn nnnnnn (nnnnnnn nn nnnnn). Nnnnnn\n>>>>>>>>>>>
 >>>> nnnnnnnnn\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>> nnnnnn nn nnnn n-nnnn\, nnn
 nnnn nn nnnn nnnnnnn nnnnnn nn\n>>>>>>>>>>>>>>> nnnnnnnnn nn\n>>>>>>>>>>>>
 >\n>>>>>>>>>>>>>>> n nnnnnnn nn nnnnnnnnnn nnnnnnnnn. Nnn nnnnnnnnnn\n>>>>
 >>>>>>>>>>> nnnnnnnnn\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>> nnnnnnnnnnn nnn nnnn
 nnnnnnn nnnnnnnnn NNN'n nnnnnnnn nnn\n>>>>>>>>>>>>>>> nnnnnnnn\,\n>>>>>>>>
 >>>>>\n>>>>>>>>>>>>>>> nnnnnn nnnnn nn nnn nnnnnnnnn\n>>>>>>>>>>>>>\n>>>>>
 >>>>>>>>>> nnnn:\n>>>>>>>>>>>>>\n>>>>>>>>>>>>>>>\n>>>>>>>>>>>>>\n>>>>>>>>>
 >>>>>> nnnn://nnn.nnn.nnn/nnnnn/nnnnnn-nnnnnnnnnnn\n>>>>>>>>>>>>>\n>>>>>>>
 >>>>>> Nnnn n-nnnn nnn nnn nnnnnnnnnnn nnn nnnnnnnn nnnn nnn nnn\n>>>>>>>>
 >>>>> nnnnnnnnnn nn nnnnnn nn nnnn nn nn nnnnnnnnn nnn nnn\n>>>>>>>>>>>>> 
 nnnnnnn nnnnnnnnnnn nnnn nn nnnnnnnnnnnn\, nnnnnnnnnn\,\n>>>>>>>>>>>>> nnn
 nnn nnnnnnnnnnn\, nn nnnnnnn nn nnnnn nnnnnnnnnnnn nn\n>>>>>>>>>>>>> nnn n
 n nnnnnnnnnn. Nnn nnnnnnnnnnnn nnn\, nnnnnnnnnnnnn nn nnnnnnn nn nnnn nnnn
 nnnnnnnn nn nnn nnnnnnnnnnn nn nn nn nnnnnnnnnn nnn nnn nn nnnnnnnn. Nn nn
 n nnnn nnnnnnnn nnnn nnnnnnnnnnnn nn nnnnn\, nnnnnn nnnnnn nnn nnnnnn nnnn
 nnnnnnn nn nnnnnn n-nnnn\, nnn nnnnnnnnnnn nnnnnn nn nnnnnnn nnnn n-nnnn\,
  nnn nnnnnnnnnnn\, nnn nnn nnnnnn (nnnnnnn nn nnnnn). Nnnnnn nnnnnnnnn nnn
 nnn nn nnnn n-nnnn\, nnnnnnn nn nnnn nnnnnnn nnnnnn nn nnnnnnnnn nn n nnnn
 nnn nn nnnnnnnnnn nnnnnnnnn. Nnn nnnnnnnnnn nnnnnnnnn nnnnnnnnnnn nnn nnnn
 nnnnnnn nnnnnnnnn NNN’n nnnnnnnn nnn nnnnnnnn\, nnnnnn nnnnn nn nnn nnnn
 nnnnn nnnn:\n>>>>>>>>>>>>>\n>>>>>>>>>>>>> nnnn://nnn.nnn.nnn/nnnnn/nnnnnn-
 nnnnnnnnnnn\n>>>>>>>>>>>> Nnnn n-nnnn nnn nnn nnnnnnnnnnn nnn nnnnnnnn nnn
 n nnn nnn nnnnnnnnnn nn nnnnnn nn nnnn nn nn nnnnnnnnn nnn nnn nnnnnnn nnn
 nnnnnnnn nnnn nn nnnnnnnnnnnn\, nnnnnnnnnn\, nnnnnn nnnnnnnnnnn\, nn nnnnn
 nn nn nnnnn nnnnnnnnnnnn nn nnn nn nnnnnnnnnn. Nnn nnnnnnnnnnnn nnn\, nnnn
 nnnnnnnnn nn nnnnnnn nn nnnn nnnnnnnnnnnn nn nnn nnnnnnnnnnn nn nn nn nnnn
 nnnnnn nnn nnn nn nnnnnnnn. Nn nnn nnnn nnnnnnnn nnnn nnnnnnnnnnnn nn nnnn
 n\, nnnnnn nnnnnn nnn nnnnnn nnnnnnnnnnn nn nnnnnn n-nnnn\, nnn nnnnnnnnnn
 n nnnnnn nn nnnnnnn nnnn n-nnnn\, nnn nnnnnnnnnnn\, nnn nnn nnnnnn (nnnnnn
 n nn nnnnn). Nnnnnn nnnnnnnnn nnnnnn nn nnnn n-nnnn\, nnnnnnn nn nnnn nnnn
 nnn nnnnnn nn nnnnnnnnn nn n nnnnnnn nn nnnnnnnnnn nnnnnnnnn. Nnn nnnnnnnn
 nn nnnnnnnnn nnnnnnnnnnn nnn nnnnnnnnnnn nnnnnnnnn NNN’n nnnnnnnn nnn nn
 nnnnnn\, nnnnnn nnnnn nn nnn nnnnnnnnn nnnn:\n>>>>>>>>>>>>\n>>>>>>>>>>>> n
 nnn://nnn.nnn.nnn/nnnnn/nnnnnn-nnnnnnnnnnn\n>>>>>>>>>>> Nnnn n-nnnn nnn nn
 n nnnnnnnnnnn nnn nnnnnnnn nnnn nnn nnn nnnnnnnnnn nn nnnnnn nn nnnn nn nn
  nnnnnnnnn nnn nnn nnnnnnn nnnnnnnnnnn nnnn nn nnnnnnnnnnnn\, nnnnnnnnnn\,
  nnnnnn nnnnnnnnnnn\, nn nnnnnnn nn nnnnn nnnnnnnnnnnn nn nnn nn nnnnnnnnn
 n. Nnn nnnnnnnnnnnn nnn\, nnnnnnnnnnnnn nn nnnnnnn nn nnnn nnnnnnnnnnnn nn
  nnn nnnnnnnnnnn nn nn nn nnnnnnnnnn nnn nnn nn nnnnnnnn. Nn nnn nnnn nnnn
 nnnn nnnn nnnnnnnnnnnn nn nnnnn\, nnnnnn nnnnnn nnn nnnnnn nnnnnnnnnnn nn 
 nnnnnn n-nnnn\, nnn nnnnnnnnnnn nnnnnn nn nnnnnnn nnnn n-nnnn\, nnn nnnnnn
 nnnnn\, nnn nnn nnnnnn (nnnnnnn nn nnnnn). Nnnnnn nnnnnnnnn nnnnnn nn nnnn
  n-nnnn\, nnnnnnn nn nnnn nnnnnnn nnnnnn nn nnnnnnnnn nn n nnnnnnn nn nnnn
 nnnnnn nnnnnnnnn. Nnn nnnnnnnnnn nnnnnnnnn nnnnnnnnnnn nnn nnnnnnnnnnn nnn
 nnnnnn NNN’n nnnnnnnn nnn nnnnnnnn\, nnnnnn nnnnn nn nnn nnnnnnnnn nnnn:
 \n>>>>>>>>>>>\n>>>>>>>>>>> nnnn://nnn.nnn.nnn/nnnnn/nnnnnn-nnnnnnnnnnn\n>>
 >>>>>>>> Nnnn n-nnnn nnn nnn nnnnnnnnnnn nnn nnnnnnnn nnnn nnn nnn nnnnnnn
 nnn nn nnnnnn nn nnnn nn nn nnnnnnnnn nnn nnn nnnnnnn nnnnnnnnnnn nnnn nn 
 nnnnnnnnnnnn\, nnnnnnnnnn\, nnnnnn nnnnnnnnnnn\, nn nnnnnnn nn nnnnn nnnnn
 nnnnnnn nn nnn nn nnnnnnnnnn. Nnn nnnnnnnnnnnn nnn\, nnnnnnnnnnnnn nn nnnn
 nnn nn nnnn nnnnnnnnnnnn nn nnn nnnnnnnnnnn nn nn nn nnnnnnnnnn nnn nnn nn
  nnnnnnnn. Nn nnn nnnn nnnnnnnn nnnn nnnnnnnnnnnn nn nnnnn\, nnnnnn nnnnnn
  nnn nnnnnn nnnnnnnnnnn nn nnnnnn n-nnnn\, nnn nnnnnnnnnnn nnnnnn nn nnnnn
 nn nnnn n-nnnn\, nnn nnnnnnnnnnn\, nnn nnn nnnnnn (nnnnnnn nn nnnnn). Nnnn
 nn nnnnnnnnn nnnnnn nn nnnn n-nnnn\, nnnnnnn nn nnnn nnnnnnn nnnnnn nn nnn
 nnnnnn nn n nnnnnnn nn nnnnnnnnnn nnnnnnnnn. Nnn nnnnnnnnnn nnnnnnnnn nnnn
 nnnnnnn nnn nnnnnnnnnnn nnnnnnnnn NNN’n nnnnnnnn nnn nnnnnnnn\, nnnnnn n
 nnnn nn nnn nnnnnnnnn nnnn:\n>>>>>>>>>>\n>>>>>>>>>> nnnn://nnn.nnn.nnn/nnn
 nn/nnnnnn-nnnnnnnnnnn\n>>>>>>>> Nnnn n-nnnn nnn nnn nnnnnnnnnnn nnn nnnnnn
 nn nnnn nnn nnn nnnnnnnnnn nn nnnnnn nn nnnn nn nn nnnnnnnnn nnn nnn nnnnn
 nn nnnnnnnnnnn nnnn nn nnnnnnnnnnnn\, nnnnnnnnnn\, nnnnnn nnnnnnnnnnn\, nn
  nnnnnnn nn nnnnn nnnnnnnnnnnn nn nnn nn nnnnnnnnnn. Nnn nnnnnnnnnnnn nnn\
 , nnnnnnnnnnnnn nn nnnnnnn nn nnnn nnnnnnnnnnnn nn nnn nnnnnnnnnnn nn nn n
 n nnnnnnnnnn nnn nnn nn nnnnnnnn. Nn nnn nnnn nnnnnnnn nnnn nnnnnnnnnnnn n
 n nnnnn\, nnnnnn nnnnnn nnn nnnnnn nnnnnnnnnnn nn nnnnnn n-nnnn\, nnn nnnn
 nnnnnnn nnnnnn nn nnnnnnn nnnn n-nnnn\, nnn nnnnnnnnnnn\, nnn nnn nnnnnn (
 nnnnnnn nn nnnnn). Nnnnnn nnnnnnnnn nnnnnn nn nnnn n-nnnn\, nnnnnnn nn nnn
 n nnnnnnn nnnnnn nn nnnnnnnnn nn n nnnnnnn nn nnnnnnnnnn nnnnnnnnn. Nnn nn
 nnnnnnnn nnnnnnnnn nnnnnnnnnnn nnn nnnnnnnnnnn nnnnnnnnn NNN’n nnnnnnnn 
 nnn nnnnnnnn\, nnnnnn nnnnn nn nnn nnnnnnnnn nnnn:\n>>>>>>>>\n>>>>>>>> nnn
 n://nnn.nnn.nnn/nnnnn/nnnnnn-nnnnnnnnnnn\n>>>>>>> Nnnn n-nnnn nnn nnn nnnn
 nnnnnnn nnn nnnnnnnn nnnn nnn nnn nnnnnnnnnn nn nnnnnn nn nnnn nn nn nnnnn
 nnnn nnn nnn nnnnnnn nnnnnnnnnnn nnnn nn nnnnnnnnnnnn\, nnnnnnnnnn\, nnnnn
 n nnnnnnnnnnn\, nn nnnnnnn nn nnnnn nnnnnnnnnnnn nn nnn nn nnnnnnnnnn. Nnn
  nnnnnnnnnnnn nnn\, nnnnnnnnnnnnn nn nnnnnnn nn nnnn nnnnnnnnnnnn nn nnn n
 nnnnnnnnnn nn nn nn nnnnnnnnnn nnn nnn nn nnnnnnnn. Nn nnn nnnn nnnnnnnn n
 nnn nnnnnnnnnnnn nn nnnnn\, nnnnnn nnnnnn nnn nnnnnn nnnnnnnnnnn nn nnnnnn
  n-nnnn\, nnn nnnnnnnnnnn nnnnnn nn nnnnnnn nnnn n-nnnn\, nnn nnnnnnnnnnn\
 , nnn nnn nnnnnn (nnnnnnn nn nnnnn). Nnnnnn nnnnnnnnn nnnnnn nn nnnn n-nnn
 n\, nnnnnnn nn nnnn nnnnnnn nnnnnn nn nnnnnnnnn nn n nnnnnnn nn nnnnnnnnnn
  nnnnnnnnn. Nnn nnnnnnnnnn nnnnnnnnn nnnnnnnnnnn nnn nnnnnnnnnnn nnnnnnnnn
  NNN’n nnnnnnnn nnn nnnnnnnn\, nnnnnn nnnnn nn nnn nnnnnnnnn nnnn:\n>>>>
 >>>\n>>>>>>> nnnn://nnn.nnn.nnn/nnnnn/nnnnnn-nnnnnnnnnnn\n>>>>>>\n>>>>>> N
 nnn n-nnnn nnn nnn nnnnnnnnnnn nnn nnnnnnnn nnnn nnn nnn nnnnnnnnnn nn nnn
 nnn nn nnnn nn nn nnnnnnnnn nnn nnn nnnnnnn nnnnnnnnnnn nnnn nn nnnnnnnnnn
 nn\, nnnnnnnnnn\, nnnnnn nnnnnnnnnnn\, nn nnnnnnn nn nnnnn nnnnnnnnnnnn nn
  nnn nn nnnnnnnnnn. Nnn nnnnnnnnnnnn nnn\, nnnnnnnnnnnnn nn nnnnnnn nn nnn
 n nnnnnnnnnnnn nn nnn nnnnnnnnnnn nn nn nn nnnnnnnnnn nnn nnn nn nnnnnnnn.
  Nn nnn nnnn nnnnnnnn nnnn nnnnnnnnnnnn nn nnnnn\, nnnnnn nnnnnn nnn nnnnn
 n nnnnnnnnnnn nn nnnnnn n-nnnn\, nnn nnnnnnnnnnn nnnnnn nn nnnnnnn nnnn n-
 nnnn\, nnn nnnnnnnnnnn\, nnn nnn nnnnnn (nnnnnnn nn nnnnn). Nnnnnn nnnnnnn
 nn nnnnnn nn nnnn n-nnnn\, nnnnnnn nn nnnn nnnnnnn nnnnnn nn nnnnnnnnn nn 
 n nnnnnnn nn nnnnnnnnnn nnnnnnnnn. Nnn nnnnnnnnnn nnnnnnnnn nnnnnnnnnnn nn
 n nnnnnnnnnnn nnnnnnnnn NNN’n nnnnnnnn nnn nnnnnnnn\, nnnnnn nnnnn nn nn
 n nnnnnnnnn nnnn:\n>>>>>>\n>>>>>> nnnn://nnn.nnn.nnn/nnnnn/nnnnnn-nnnnnnnn
 nnn\n>>>>> Nnnn n-nnnn nnn nnn nnnnnnnnnnn nnn nnnnnnnn nnnn nnn nnn nnnnn
 nnnnn nn nnnnnn nn nnnn nn nn nnnnnnnnn nnn nnn nnnnnnn nnnnnnnnnnn nnnn n
 n nnnnnnnnnnnn\, nnnnnnnnnn\, nnnnnn nnnnnnnnnnn\, nn nnnnnnn nn nnnnn nnn
 nnnnnnnnn nn nnn nn nnnnnnnnnn. Nnn nnnnnnnnnnnn nnn\, nnnnnnnnnnnnn nn nn
 nnnnn nn nnnn nnnnnnnnnnnn nn nnn nnnnnnnnnnn nn nn nn nnnnnnnnnn nnn nnn 
 nn nnnnnnnn. Nn nnn nnnn nnnnnnnn nnnn nnnnnnnnnnnn nn nnnnn\, nnnnnn nnnn
 nn nnn nnnnnn nnnnnnnnnnn nn nnnnnn n-nnnn\, nnn nnnnnnnnnnn nnnnnn nn nnn
 nnnn nnnn n-nnnn\, nnn nnnnnnnnnnn\, nnn nnn nnnnnn (nnnnnnn nn nnnnn). Nn
 nnnn nnnnnnnnn nnnnnn nn nnnn n-nnnn\, nnnnnnn nn nnnn nnnnnnn nnnnnn nn n
 nnnnnnnn nn n nnnnnnn nn nnnnnnnnnn nnnnnnnnn. Nnn nnnnnnnnnn nnnnnnnnn nn
 nnnnnnnnn nnn nnnnnnnnnnn nnnnnnnnn NNN’n nnnnnnnn nnn nnnnnnnn\, nnnnnn
  nnnnn nn nnn nnnnnnnnn nnnn:\n>>>>>\n>>>>> nnnn://nnn.nnn.nnn/nnnnn/nnnnn
 n-nnnnnnnnnnn\n>>>> Nnnn n-nnnn nnn nnn nnnnnnnnnnn nnn nnnnnnnn nnnn nnn 
 nnn nnnnnnnnnn nn nnnnnn nn nnnn nn nn nnnnnnnnn nnn nnn nnnnnnn nnnnnnnnn
 nn nnnn nn nnnnnnnnnnnn\, nnnnnnnnnn\, nnnnnn nnnnnnnnnnn\, nn nnnnnnn nn 
 nnnnn nnnnnnnnnnnn nn nnn nn nnnnnnnnnn. Nnn nnnnnnnnnnnn nnn\, nnnnnnnnnn
 nnn nn nnnnnnn nn nnnn nnnnnnnnnnnn nn nnn nnnnnnnnnnn nn nn nn nnnnnnnnnn
  nnn nnn nn nnnnnnnn. Nn nnn nnnn nnnnnnnn nnnn nnnnnnnnnnnn nn nnnnn\, nn
 nnnn nnnnnn nnn nnnnnn nnnnnnnnnnn nn nnnnnn n-nnnn\, nnn nnnnnnnnnnn nnnn
 nn nn nnnnnnn nnnn n-nnnn\, nnn nnnnnnnnnnn\, nnn nnn nnnnnn (nnnnnnn nn n
 nnnn). Nnnnnn nnnnnnnnn nnnnnn nn nnnn n-nnnn\, nnnnnnn nn nnnn nnnnnnn nn
 nnnn nn nnnnnnnnn nn n nnnnnnn nn nnnnnnnnnn nnnnnnnnn. Nnn nnnnnnnnnn nnn
 nnnnnn nnnnnnnnnnn nnn nnnnnnnnnnn nnnnnnnnn NNN’n nnnnnnnn nnn nnnnnnnn
 \, nnnnnn nnnnn nn nnn nnnnnnnnn nnnn:\n>>>>\n>>>> nnnn://nnn.nnn.nnn/nnnn
 n/nnnnnn-nnnnnnnnnnn\n>>> Nnnn n-nnnn nnn nnn nnnnnnnnnnn nnn nnnnnnnn nnn
 n nnn nnn nnnnnnnnnn nn nnnnnn nn nnnn nn nn nnnnnnnnn nnn nnn nnnnnnn nnn
 nnnnnnnn nnnn nn nnnnnnnnnnnn\, nnnnnnnnnn\, nnnnnn nnnnnnnnnnn\, nn nnnnn
 nn nn nnnnn nnnnnnnnnnnn nn nnn nn nnnnnnnnnn. Nnn nnnnnnnnnnnn nnn\, nnnn
 nnnnnnnnn nn nnnnnnn nn nnnn nnnnnnnnnnnn nn nnn nnnnnnnnnnn nn nn nn nnnn
 nnnnnn nnn nnn nn nnnnnnnn. Nn nnn nnnn nnnnnnnn nnnn nnnnnnnnnnnn nn nnnn
 n\, nnnnnn nnnnnn nnn nnnnnn nnnnnnnnnnn nn nnnnnn n-nnnn\, nnn nnnnnnnnnn
 n nnnnnn nn nnnnnnn nnnn n-nnnn\, nnn nnnnnnnnnnn\, nnn nnn nnnnnn (nnnnnn
 n nn nnnnn). Nnnnnn nnnnnnnnn nnnnnn nn nnnn n-nnnn\, nnnnnnn nn nnnn nnnn
 nnn nnnnnn nn nnnnnnnnn nn n nnnnnnn nn nnnnnnnnnn nnnnnnnnn. Nnn nnnnnnnn
 nn nnnnnnnnn nnnnnnnnnnn nnn nnnnnnnnnnn nnnnnnnnn NNN’n nnnnnnnn nnn nn
 nnnnnn\, nnnnnn nnnnn nn nnn nnnnnnnnn nnnn:\n>>>\n>>> nnnn://nnn.nnn.nnn/
 nnnnn/nnnnnn-nnnnnnnnnnn\n>> Nnnn n-nnnn nnn nnn nnnnnnnnnnn nnn nnnnnnnn 
 nnnn nnn nnn nnnnnnnnnn nn nnnnnn nn nnnn nn nn nnnnnnnnn nnn nnn nnnnnnn 
 nnnnnnnnnnn nnnn nn nnnnnnnnnnnn\, nnnnnnnnnn\, nnnnnn nnnnnnnnnnn\, nn nn
 nnnnn nn nnnnn nnnnnnnnnnnn nn nnn nn nnnnnnnnnn. Nnn nnnnnnnnnnnn nnn\, n
 nnnnnnnnnnnn nn nnnnnnn nn nnnn nnnnnnnnnnnn nn nnn nnnnnnnnnnn nn nn nn n
 nnnnnnnnn nnn nnn nn nnnnnnnn. Nn nnn nnnn nnnnnnnn nnnn nnnnnnnnnnnn nn n
 nnnn\, nnnnnn nnnnnn nnn nnnnnn nnnnnnnnnnn nn nnnnnn n-nnnn\, nnn nnnnnnn
 nnnn nnnnnn nn nnnnnnn nnnn n-nnnn\, nnn nnnnnnnnnnn\, nnn nnn nnnnnn (nnn
 nnnn nn nnnnn). Nnnnnn nnnnnnnnn nnnnnn nn nnnn n-nnnn\, nnnnnnn nn nnnn n
 nnnnnn nnnnnn nn nnnnnnnnn nn n nnnnnnn nn nnnnnnnnnn nnnnnnnnn. Nnn nnnnn
 nnnnn nnnnnnnnn nnnnnnnnnnn nnn nnnnnnnnnnn nnnnnnnnn NNN’n nnnnnnnn nnn
  nnnnnnnn\, nnnnnn nnnnn nn nnn nnnnnnnnn nnnn:\n>>\n>> nnnn://nnn.nnn.nnn
 /nnnnn/nnnnnn-nnnnnnnnnnn\n>>\n>>\n> Nnnn n-nnnn nnn nnn nnnnnnnnnnn nnn n
 nnnnnnn nnnn nnn nnn nnnnnnnnnn nn nnnnnn nn nnnn nn nn nnnnnnnnn nnn nnn 
 nnnnnnn nnnnnnnnnnn nnnn nn nnnnnnnnnnnn\, nnnnnnnnnn\, nnnnnn nnnnnnnnnnn
 \, nn nnnnnnn nn nnnnn nnnnnnnnnnnn nn nnn nn nnnnnnnnnn. Nnn nnnnnnnnnnnn
  nnn\, nnnnnnnnnnnnn nn nnnnnnn nn nnnn nnnnnnnnnnnn nn nnn nnnnnnnnnnn nn
  nn nn nnnnnnnnnn nnn nnn nn nnnnnnnn. Nn nnn nnnn nnnnnnnn nnnn nnnnnnnnn
 nnn nn nnnnn\, nnnnnn nnnnnn nnn nnnnnn nnnnnnnnnnn nn nnnnnn n-nnnn\, nnn
  nnnnnnnnnnn nnnnnn nn nnnnnnn nnnn n-nnnn\, nnn nnnnnnnnnnn\, nnn nnn nnn
 nnn (nnnnnnn nn nnnnn). Nnnnnn nnnnnnnnn nnnnnn nn nnnn n-nnnn\, nnnnnnn n
 n nnnn nnnnnnn nnnnnn nn nnnnnnnnn nn n nnnnnnn nn nnnnnnnnnn nnnnnnnnn. N
 nn nnnnnnnnnn nnnnnnnnn nnnnnnnnnnn nnn nnnnnnnnnnn nnnnnnnnn NNN’n nnnn
 nnnn nnn nnnnnnnn\, nnnnnn nnnnn nn nnn nnnnnnnnn nnnn:\n>\n> nnnn://nnn.n
 nn.nnn/nnnnn/nnnnnn-nnnnnnnnnnn\n\nNnnn n-nnnn nnn nnn nnnnnnnnnnn nnn nnn
 nnnnn nnnn nnn nnn nnnnnnnnnn nn nnnnnn nn nnnn nn nn nnnnnnnnn nnn nnn nn
 nnnnn nnnnnnnnnnn nnnn nn nnnnnnnnnnnn\, nnnnnnnnnn\, nnnnnn nnnnnnnnnnn\,
  nn nnnnnnn nn nnnnn nnnnnnnnnnnn nn nnn nn nnnnnnnnnn. Nnn nnnnnnnnnnnn n
 nn\, nnnnnnnnnnnnn nn nnnnnnn nn nnnn nnnnnnnnnnnn nn nnn nnnnnnnnnnn nn n
 n nn nnnnnnnnnn nnn nnn nn nnnnnnnn. Nn nnn nnnn nnnnnnnn nnnn nnnnnnnnnnn
 n nn nnnnn\, nnnnnn nnnnnn nnn nnnnnn nnnnnnnnnnn nn nnnnnn n-nnnn\, nnn n
 nnnnnnnnnn nnnnnn nn nnnnnnn nnnn n-nnnn\, nnn nnnnnnnnnnn\, nnn nnn nnnnn
 n (nnnnnnn nn nnnnn). Nnnnnn nnnnnnnnn nnnnnn nn nnnn n-nnnn\, nnnnnnn nn 
 nnnn nnnnnnn nnnnnn nn nnnnnnnnn nn n nnnnnnn nn nnnnnnnnnn nnnnnnnnn. Nnn
  nnnnnnnnnn nnnnnnnnn nnnnnnnnnnn nnn nnnnnnnnnnn nnnnnnnnn NNN’n nnnnnn
 nn nnn nnnnnnnn\, nnnnnn nnnnn nn nnn nnnnnnnnn nnnn:\n\nnnnn://nnn.nnn.nn
 n/nnnnn/nnnnnn-nnnnnnnnnnn\n

[-- Attachment #3: Type: text/plain, Size: 89 bytes --]


Here is my analysis from
https://debbugs.gnu.org/cgi/bugreport.cgi?bug=24358#27 again:


[-- Attachment #4: Type: message/rfc822, Size: 3206 bytes --]

Subject: bug#24358: 25.1.50; re-search-forward errors with "Variable binding depth exceeds max-specpdl-size"
Date: Sat, 03 Sep 2016 11:43:16 -0400

> (I'm also on GNU/Linux, Arch) I get the same max-specpdl-size error
> with 25.1.50 [this refers to the master branch which is now 26.0.50
> (emacs-25 was 25.0.xx at the time)].  With emacs version 24.5 (and
> below) I get (error "Stack overflow in regexp matcher") [as expected].

The problem is that re_max_failures is set to 40001 (instead of the
original 40000) in main()[1], which is a problem because of the
GROW_FAIL_STACK uses (re_max_failures * TYPICAL_FAILURE_SIZE) as a cap
on the amount to allocate, but ((fail_stack).size * sizeof
(fail_stack_elt_t)) to calculate current allocation.

Since TYPICAL_FAILURE_SIZE = 20 and sizeof (fail_stack_elt_t) = 8, and
it seems that (fail_stack).size grows in increments of 3, when
(fail_stack).avail is 99999 and (fail_stack).size reaches 100002:

(fail_stack).size * sizeof (fail_stack_elt_t) => 800016
  re_max_failures * TYPICAL_FAILURE_SIZE      => 800020

ENSURE_FAIL_STACK(3) then loops indefinitely reallocating a stack of
size 800020 again and again until the record_xmalloc fails to
grow_specdl() (thus the "max-specpdl-size" error).

----------

So we we might want to fix the re_max_failures setting in main, but it
doesn't quite make sense to me that GROW_FAIL_STACK relies on
re_max_failures being a multiple of (sizeof (fail_stack_elt_t)).  At the
definition of TYPICAL_FAILURE_SIZE we have

/* Estimate the size of data pushed by a typical failure stack entry.
   An estimate is all we need, because all we use this for
   is to choose a limit for how big to make the failure stack.  */
/* BEWARE, the value `20' is hard-coded in emacs.c:main().  */
#define TYPICAL_FAILURE_SIZE 20

Why do we use an "estimate" here?  What's wrong with just using
(re_max_failures * sizeof (fail_stack_elt_t)) as the limit?  Or should
the limit actually be (re_max_failures * TYPICAL_FAILURE_SIZE * sizeof
(fail_stack_elt_t))?

-----------

827	      long lim = rlim.rlim_cur;
(gdb) p rlim
$1 = {
  rlim_cur = 8388608, 
  rlim_max = 18446744073709551615
}
(gdb) next
833	      int ratio = 20 * sizeof (char *);
(gdb) 
834	      ratio += ratio / 3;
(gdb) 
837	      int extra = 200000;
(gdb) p ratio
$2 = 213
[...]
(gdb) display ((newlim - extra) / ratio)
1: ((newlim - extra) / ratio) = 40000
(gdb) next
856		  newlim += pagesize - 1;
1: ((newlim - extra) / ratio) = 40000
(gdb) 
857		  if (0 <= rlim.rlim_max && rlim.rlim_max < newlim)
1: ((newlim - extra) / ratio) = 40019
(gdb) 
859		  newlim -= newlim % pagesize;
1: ((newlim - extra) / ratio) = 40019
(gdb) 
861		  if (pagesize <= newlim - lim)
1: ((newlim - extra) / ratio) = 40001
(gdb) undisplay 1
(gdb) next
863		      rlim.rlim_cur = newlim;
(gdb) 
864		      if (setrlimit (RLIMIT_STACK, &rlim) == 0)
(gdb) 
865			lim = newlim;
(gdb) 
870	      re_max_failures = lim < extra ? 0 : min (lim - extra, SIZE_MAX) / ratio;
(gdb) 
875	  stack_bottom = &stack_bottom_variable;
(gdb) p re_max_failures
$3 = 40001

-----------

[1]: This was the case since 9d356f62 2016-05-27 "Robustify stack-size calculation"


^ permalink raw reply	[flat|nested] 22+ messages in thread

* bug#24751: 26.0.50; Regex stack overflow not detected properly (gets "Variable binding depth exceeds max-specpdl-size")
  2016-10-21  3:54 bug#24751: 26.0.50; Regex stack overflow not detected properly (gets "Variable binding depth exceeds max-specpdl-size") npostavs
@ 2016-11-04  8:22 ` Eli Zaretskii
  2016-11-05 19:34   ` npostavs
  0 siblings, 1 reply; 22+ messages in thread
From: Eli Zaretskii @ 2016-11-04  8:22 UTC (permalink / raw)
  To: npostavs; +Cc: 24751

> From: npostavs@users.sourceforge.net
> Date: Thu, 20 Oct 2016 23:54:05 -0400
> 
> So we we might want to fix the re_max_failures setting in main, but it
> doesn't quite make sense to me that GROW_FAIL_STACK relies on
> re_max_failures being a multiple of (sizeof (fail_stack_elt_t)).  At the
> definition of TYPICAL_FAILURE_SIZE we have
> 
> /* Estimate the size of data pushed by a typical failure stack entry.
>    An estimate is all we need, because all we use this for
>    is to choose a limit for how big to make the failure stack.  */
> /* BEWARE, the value `20' is hard-coded in emacs.c:main().  */
> #define TYPICAL_FAILURE_SIZE 20
> 
> Why do we use an "estimate" here?  What's wrong with just using
> (re_max_failures * sizeof (fail_stack_elt_t)) as the limit?  Or should
> the limit actually be (re_max_failures * TYPICAL_FAILURE_SIZE * sizeof
> (fail_stack_elt_t))?

I think it should be the latter, indeed.

Can you propose a patch along those lines that would remove the
infloop in ENSURE_FAIL_STACK?

Thanks.





^ permalink raw reply	[flat|nested] 22+ messages in thread

* bug#24751: 26.0.50; Regex stack overflow not detected properly (gets "Variable binding depth exceeds max-specpdl-size")
  2016-11-04  8:22 ` Eli Zaretskii
@ 2016-11-05 19:34   ` npostavs
  2016-11-06 15:45     ` Eli Zaretskii
  0 siblings, 1 reply; 22+ messages in thread
From: npostavs @ 2016-11-05 19:34 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 24751

Eli Zaretskii <eliz@gnu.org> writes:

>> From: npostavs@users.sourceforge.net
>> Date: Thu, 20 Oct 2016 23:54:05 -0400
>> 
>> So we we might want to fix the re_max_failures setting in main, but it
>> doesn't quite make sense to me that GROW_FAIL_STACK relies on
>> re_max_failures being a multiple of (sizeof (fail_stack_elt_t)).  At the
>> definition of TYPICAL_FAILURE_SIZE we have
>> 
>> /* Estimate the size of data pushed by a typical failure stack entry.
>>    An estimate is all we need, because all we use this for
>>    is to choose a limit for how big to make the failure stack.  */
>> /* BEWARE, the value `20' is hard-coded in emacs.c:main().  */
>> #define TYPICAL_FAILURE_SIZE 20
>> 
>> Why do we use an "estimate" here?  What's wrong with just using
>> (re_max_failures * sizeof (fail_stack_elt_t)) as the limit?  Or should
>> the limit actually be (re_max_failures * TYPICAL_FAILURE_SIZE * sizeof
>> (fail_stack_elt_t))?
>
> I think it should be the latter, indeed.
>
> Can you propose a patch along those lines that would remove the
> infloop in ENSURE_FAIL_STACK?
>
> Thanks.

The below seems to work, but effectively increases the size of the
failure stack (so the sample file size has to be increased 8-fold to get
a regex stack overflow).  Strangely, changing the value in the
definition of re_max_failures doesn't seem to have any effect, it stays
40000 regardless.  I am quite confused.

diff --git i/src/regex.c w/src/regex.c
index 1c6c9e5..163c5b4 100644
--- i/src/regex.c
+++ w/src/regex.c
@@ -1320,19 +1320,22 @@ WEAK_ALIAS (__re_set_syntax, re_set_syntax)
 
 #define GROW_FAIL_STACK(fail_stack)					\
   (((fail_stack).size * sizeof (fail_stack_elt_t)			\
-    >= re_max_failures * TYPICAL_FAILURE_SIZE)				\
+    >= re_max_failures * sizeof (fail_stack_elt_t)                      \
+    * TYPICAL_FAILURE_SIZE)                                             \
    ? 0									\
    : ((fail_stack).stack						\
       = REGEX_REALLOCATE_STACK ((fail_stack).stack,			\
 	  (fail_stack).size * sizeof (fail_stack_elt_t),		\
-	  min (re_max_failures * TYPICAL_FAILURE_SIZE,			\
+	  min (re_max_failures * sizeof (fail_stack_elt_t)              \
+               * TYPICAL_FAILURE_SIZE,                                  \
 	       ((fail_stack).size * sizeof (fail_stack_elt_t)		\
 		* FAIL_STACK_GROWTH_FACTOR))),				\
 									\
       (fail_stack).stack == NULL					\
       ? 0								\
       : ((fail_stack).size						\
-	 = (min (re_max_failures * TYPICAL_FAILURE_SIZE,		\
+         = (min (re_max_failures * sizeof (fail_stack_elt_t)            \
+                 * TYPICAL_FAILURE_SIZE,                                \
 		 ((fail_stack).size * sizeof (fail_stack_elt_t)		\
 		  * FAIL_STACK_GROWTH_FACTOR))				\
 	    / sizeof (fail_stack_elt_t)),				\







^ permalink raw reply related	[flat|nested] 22+ messages in thread

* bug#24751: 26.0.50; Regex stack overflow not detected properly (gets "Variable binding depth exceeds max-specpdl-size")
  2016-11-05 19:34   ` npostavs
@ 2016-11-06 15:45     ` Eli Zaretskii
  2016-11-13  5:39       ` npostavs
  0 siblings, 1 reply; 22+ messages in thread
From: Eli Zaretskii @ 2016-11-06 15:45 UTC (permalink / raw)
  To: npostavs; +Cc: 24751

> From: npostavs@users.sourceforge.net
> Cc: 24751@debbugs.gnu.org
> Date: Sat, 05 Nov 2016 15:34:29 -0400
> 
> >> #define TYPICAL_FAILURE_SIZE 20
> >> 
> >> Why do we use an "estimate" here?  What's wrong with just using
> >> (re_max_failures * sizeof (fail_stack_elt_t)) as the limit?  Or should
> >> the limit actually be (re_max_failures * TYPICAL_FAILURE_SIZE * sizeof
> >> (fail_stack_elt_t))?
> >
> > I think it should be the latter, indeed.
> >
> > Can you propose a patch along those lines that would remove the
> > infloop in ENSURE_FAIL_STACK?
> >
> > Thanks.
> 
> The below seems to work

Thanks.

I think the patch can be simplified, where we now multiply by the size
of fail_stack_elt_t and then divide by it: simply remove both the
multiplication and the division.  That will make the code easier to
read, and will make the units of each variable clear, something that I
think is at the heart of this issue.

> but effectively increases the size of the failure stack (so the
> sample file size has to be increased 8-fold to get a regex stack
> overflow).

Which IMO is exactly TRT, since re_max_failures was computed given the
runtime stack size of 8MB, so having it bail out after merely 800KB
doesn't sound right to me, don't you agree?

> Strangely, changing the value in the definition of re_max_failures
> doesn't seem to have any effect, it stays 40000 regardless.  I am
> quite confused.

I don't think I follow.  Can you tell what you tried to change, and
where did you see the lack of any effect?





^ permalink raw reply	[flat|nested] 22+ messages in thread

* bug#24751: 26.0.50; Regex stack overflow not detected properly (gets "Variable binding depth exceeds max-specpdl-size")
  2016-11-06 15:45     ` Eli Zaretskii
@ 2016-11-13  5:39       ` npostavs
  2016-11-13 16:12         ` Eli Zaretskii
  0 siblings, 1 reply; 22+ messages in thread
From: npostavs @ 2016-11-13  5:39 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 24751

[-- Attachment #1: Type: text/plain, Size: 376 bytes --]

Eli Zaretskii <eliz@gnu.org> writes:

>
> I think the patch can be simplified, where we now multiply by the size
> of fail_stack_elt_t and then divide by it: simply remove both the
> multiplication and the division.  That will make the code easier to
> read, and will make the units of each variable clear, something that I
> think is at the heart of this issue.

Ah, right.


[-- Attachment #2: patch --]
[-- Type: text/plain, Size: 2147 bytes --]

From 7b24484346417c8fdf46fd7ee0be1758393f13fb Mon Sep 17 00:00:00 2001
From: Noam Postavsky <npostavs@gmail.com>
Date: Sat, 5 Nov 2016 16:51:53 -0400
Subject: [PATCH v2] Fix computation of regex stack limit

The regex stack limit was being computed as the number of stack entries,
whereas it was being compared with the current size as measured in
bytes.  This could cause indefinite looping when nearing the stack limit
if re_max_failures happened not to be a multiple of sizeof
fail_stack_elt_t (Bug #24751).

* src/regex.c (GROW_FAIL_STACK): Compute both current stack size and
limit as numbers of stack entries.
---
 src/regex.c | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/src/regex.c b/src/regex.c
index 1c6c9e5..d23ba01 100644
--- a/src/regex.c
+++ b/src/regex.c
@@ -1319,23 +1319,20 @@ WEAK_ALIAS (__re_set_syntax, re_set_syntax)
 #define FAIL_STACK_GROWTH_FACTOR 4
 
 #define GROW_FAIL_STACK(fail_stack)					\
-  (((fail_stack).size * sizeof (fail_stack_elt_t)			\
-    >= re_max_failures * TYPICAL_FAILURE_SIZE)				\
+  (((fail_stack).size >= re_max_failures * TYPICAL_FAILURE_SIZE)        \
    ? 0									\
    : ((fail_stack).stack						\
       = REGEX_REALLOCATE_STACK ((fail_stack).stack,			\
 	  (fail_stack).size * sizeof (fail_stack_elt_t),		\
-	  min (re_max_failures * TYPICAL_FAILURE_SIZE,			\
-	       ((fail_stack).size * sizeof (fail_stack_elt_t)		\
-		* FAIL_STACK_GROWTH_FACTOR))),				\
+          min (re_max_failures * TYPICAL_FAILURE_SIZE,                  \
+               ((fail_stack).size * FAIL_STACK_GROWTH_FACTOR))          \
+          * sizeof (fail_stack_elt_t)),                                 \
 									\
       (fail_stack).stack == NULL					\
       ? 0								\
       : ((fail_stack).size						\
-	 = (min (re_max_failures * TYPICAL_FAILURE_SIZE,		\
-		 ((fail_stack).size * sizeof (fail_stack_elt_t)		\
-		  * FAIL_STACK_GROWTH_FACTOR))				\
-	    / sizeof (fail_stack_elt_t)),				\
+         = (min (re_max_failures * TYPICAL_FAILURE_SIZE,                \
+                 ((fail_stack).size * FAIL_STACK_GROWTH_FACTOR))),      \
 	 1)))
 
 
-- 
2.9.3


[-- Attachment #3: Type: text/plain, Size: 2448 bytes --]



>
>> but effectively increases the size of the failure stack (so the
>> sample file size has to be increased 8-fold to get a regex stack
>> overflow).
>
> Which IMO is exactly TRT, since re_max_failures was computed given the
> runtime stack size of 8MB, so having it bail out after merely 800KB
> doesn't sound right to me, don't you agree?

Yes, I suppose we should also try to make use of the stack, rather than
calling malloc, right?  Something like this:

diff --git i/src/regex.c w/src/regex.c
index d23ba01..dcabde5 100644
--- i/src/regex.c
+++ w/src/regex.c
@@ -447,7 +447,11 @@ init_syntax_once (void)
 #else /* not REGEX_MALLOC  */
 
 # ifdef emacs
-#  define REGEX_USE_SAFE_ALLOCA USE_SAFE_ALLOCA
+#  define REGEX_USE_SAFE_ALLOCA                                         \
+  ptrdiff_t sa_avail = re_max_failures                                  \
+    * TYPICAL_FAILURE_SIZE * sizeof (fail_stack_elt_t);                 \
+  ptrdiff_t sa_count = SPECPDL_INDEX (); bool sa_must_free = false
+
 #  define REGEX_SAFE_FREE() SAFE_FREE ()
 #  define REGEX_ALLOCATE SAFE_ALLOCA
 # else



>
>> Strangely, changing the value in the definition of re_max_failures
>> doesn't seem to have any effect, it stays 40000 regardless.  I am
>> quite confused.
>
> I don't think I follow.  Can you tell what you tried to change, and
> where did you see the lack of any effect?

Modifying the initial value of re_max_failures as in the below patch,
has no effect on the size of the file at which stack regex overflow
happens (I confirmed it gets compiled by adding a #warning on the
previous line).  Printing re_max_failures in gdb still shows 40000.

diff --git i/src/regex.c w/src/regex.c
index d23ba01..d9170c0 100644
--- i/src/regex.c
+++ w/src/regex.c
@@ -1249,7 +1249,7 @@ WEAK_ALIAS (__re_set_syntax, re_set_syntax)
    whose default stack limit is 2mb.  In order for a larger
    value to work reliably, you have to try to make it accord
    with the process stack limit.  */
-size_t re_max_failures = 40000;
+size_t re_max_failures = 20;
 # else
 size_t re_max_failures = 4000;
 # endif


Actually I find Emacs still compiles if I removed that line completely,
there's just a compile warning saying

    regex.o: In function `re_match_2_internal':
    /home/npostavs/src/emacs/emacs-master/lib-src/../src/regex.c:5529: warning: the 're_max_failures' variable is obsolete and will go away.

I guess there's some kind of definition of it in libc?

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* bug#24751: 26.0.50; Regex stack overflow not detected properly (gets "Variable binding depth exceeds max-specpdl-size")
  2016-11-13  5:39       ` npostavs
@ 2016-11-13 16:12         ` Eli Zaretskii
  2016-11-15  3:08           ` npostavs
  0 siblings, 1 reply; 22+ messages in thread
From: Eli Zaretskii @ 2016-11-13 16:12 UTC (permalink / raw)
  To: npostavs; +Cc: 24751

> From: npostavs@users.sourceforge.net
> Cc: 24751@debbugs.gnu.org
> Date: Sun, 13 Nov 2016 00:39:39 -0500
> 
> > I think the patch can be simplified, where we now multiply by the size
> > of fail_stack_elt_t and then divide by it: simply remove both the
> > multiplication and the division.  That will make the code easier to
> > read, and will make the units of each variable clear, something that I
> > think is at the heart of this issue.
> 
> Ah, right.

Thanks, LGTM.

> >> but effectively increases the size of the failure stack (so the
> >> sample file size has to be increased 8-fold to get a regex stack
> >> overflow).
> >
> > Which IMO is exactly TRT, since re_max_failures was computed given the
> > runtime stack size of 8MB, so having it bail out after merely 800KB
> > doesn't sound right to me, don't you agree?
> 
> Yes, I suppose we should also try to make use of the stack, rather than
> calling malloc, right?  Something like this:
> 
> diff --git i/src/regex.c w/src/regex.c
> index d23ba01..dcabde5 100644
> --- i/src/regex.c
> +++ w/src/regex.c
> @@ -447,7 +447,11 @@ init_syntax_once (void)
>  #else /* not REGEX_MALLOC  */
>  
>  # ifdef emacs
> -#  define REGEX_USE_SAFE_ALLOCA USE_SAFE_ALLOCA
> +#  define REGEX_USE_SAFE_ALLOCA                                         \
> +  ptrdiff_t sa_avail = re_max_failures                                  \
> +    * TYPICAL_FAILURE_SIZE * sizeof (fail_stack_elt_t);                 \
> +  ptrdiff_t sa_count = SPECPDL_INDEX (); bool sa_must_free = false
> +

Yes.  And please also add a comment there saying that this replaces
USE_SAFE_ALLOCA.

> -size_t re_max_failures = 40000;
> +size_t re_max_failures = 20;
>  # else
>  size_t re_max_failures = 4000;
>  # endif
> 
> 
> Actually I find Emacs still compiles if I removed that line completely,
> there's just a compile warning saying
> 
>     regex.o: In function `re_match_2_internal':
>     /home/npostavs/src/emacs/emacs-master/lib-src/../src/regex.c:5529: warning: the 're_max_failures' variable is obsolete and will go away.
> 
> I guess there's some kind of definition of it in libc?

Most probably.  You should be able to see that using "nm -A".  If
that's indeed so, I think we should rename that variable to something
like emacs_re_max_failures, to avoid stomping on the libc variable..





^ permalink raw reply	[flat|nested] 22+ messages in thread

* bug#24751: 26.0.50; Regex stack overflow not detected properly (gets "Variable binding depth exceeds max-specpdl-size")
  2016-11-13 16:12         ` Eli Zaretskii
@ 2016-11-15  3:08           ` npostavs
  2016-11-15 16:12             ` Eli Zaretskii
  0 siblings, 1 reply; 22+ messages in thread
From: npostavs @ 2016-11-15  3:08 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 24751

Eli Zaretskii <eliz@gnu.org> writes:

>> 
>> Yes, I suppose we should also try to make use of the stack, rather than
>> calling malloc, right?  Something like this:
>> 
>> diff --git i/src/regex.c w/src/regex.c
>> index d23ba01..dcabde5 100644
>> --- i/src/regex.c
>> +++ w/src/regex.c
>> @@ -447,7 +447,11 @@ init_syntax_once (void)
>>  #else /* not REGEX_MALLOC  */
>>  
>>  # ifdef emacs
>> -#  define REGEX_USE_SAFE_ALLOCA USE_SAFE_ALLOCA
>> +#  define REGEX_USE_SAFE_ALLOCA                                         \
>> +  ptrdiff_t sa_avail = re_max_failures                                  \
>> +    * TYPICAL_FAILURE_SIZE * sizeof (fail_stack_elt_t);                 \
>> +  ptrdiff_t sa_count = SPECPDL_INDEX (); bool sa_must_free = false
>> +
>
> Yes.  And please also add a comment there saying that this replaces
> USE_SAFE_ALLOCA.

Actually, we should avoid increasing this limit if the stack wasn't
increased, right?  Here's what I came up with, I think it doesn't cover
Cygwin/Windows though.

diff --git c/src/emacs.c i/src/emacs.c
index b74df21..d4655c8 100644
--- c/src/emacs.c
+++ i/src/emacs.c
@@ -831,8 +831,8 @@ main (int argc, char **argv)
 	 re_max_failures, then add 33% to cover the size of the
 	 smaller stacks that regex.c successively allocates and
 	 discards on its way to the maximum.  */
-      int ratio = 20 * sizeof (char *);
-      ratio += ratio / 3;
+      int min_ratio = 20 * sizeof (char *);
+      int ratio = min_ratio + min_ratio / 3;
 
       /* Extra space to cover what we're likely to use for other reasons.  */
       int extra = 200000;
@@ -869,6 +869,7 @@ main (int argc, char **argv)
 
       /* Don't let regex.c overflow the stack.  */
       re_max_failures = lim < extra ? 0 : min (lim - extra, SIZE_MAX) / ratio;
+      emacs_re_safe_alloca = re_max_failures * min_ratio;
     }
 #endif /* HAVE_SETRLIMIT and RLIMIT_STACK and not CYGWIN */
 
diff --git c/src/regex.c i/src/regex.c
index d23ba01..56cffa1 100644
--- c/src/regex.c
+++ i/src/regex.c
@@ -447,7 +447,13 @@ init_syntax_once (void)
 #else /* not REGEX_MALLOC  */
 
 # ifdef emacs
-#  define REGEX_USE_SAFE_ALLOCA USE_SAFE_ALLOCA
+/* This may be adjusted in main(), if the stack is successfully grown.  */
+ptrdiff_t emacs_re_safe_alloca = MAX_ALLOCA;
+/* Like USE_SAFE_ALLOCA, but use emacs_re_safe_alloca.  */
+#  define REGEX_USE_SAFE_ALLOCA                                        \
+  ptrdiff_t sa_avail = emacs_re_safe_alloca;                           \
+  ptrdiff_t sa_count = SPECPDL_INDEX (); bool sa_must_free = false
+
 #  define REGEX_SAFE_FREE() SAFE_FREE ()
 #  define REGEX_ALLOCATE SAFE_ALLOCA
 # else
diff --git c/src/regex.h i/src/regex.h
index 4922440..45cbe0a 100644
--- c/src/regex.h
+++ i/src/regex.h
@@ -187,6 +187,11 @@
 /* Roughly the maximum number of failure points on the stack.  */
 extern size_t re_max_failures;
 
+#ifdef emacs
+/* Amount of memory that we can safely stack allocate.  */
+extern ptrdiff_t emacs_re_safe_alloca;
+#endif
+
 \f
 /* Define combinations of the above bits for the standard possibilities.
    (The [[[ comments delimit what gets put into the Texinfo file, so


>> 
>> 
>> Actually I find Emacs still compiles if I removed that line completely,
>> there's just a compile warning saying
>> 
>>     regex.o: In function `re_match_2_internal':
>>     /home/npostavs/src/emacs/emacs-master/lib-src/../src/regex.c:5529: warning: the 're_max_failures' variable is obsolete and will go away.
>> 
>> I guess there's some kind of definition of it in libc?
>
> Most probably.  You should be able to see that using "nm -A".  If
> that's indeed so, I think we should rename that variable to something
> like emacs_re_max_failures, to avoid stomping on the libc variable..

Ah, right:

    $ nm -A /usr/lib/libc.so.6 | grep re_max_failures
    /usr/lib/libc.so.6:0000000000000000 n __evoke_link_warning_re_max_failures
    /usr/lib/libc.so.6:00000000003981d8 D re_max_failures






^ permalink raw reply related	[flat|nested] 22+ messages in thread

* bug#24751: 26.0.50; Regex stack overflow not detected properly (gets "Variable binding depth exceeds max-specpdl-size")
  2016-11-15  3:08           ` npostavs
@ 2016-11-15 16:12             ` Eli Zaretskii
  2016-11-16  1:06               ` npostavs
  0 siblings, 1 reply; 22+ messages in thread
From: Eli Zaretskii @ 2016-11-15 16:12 UTC (permalink / raw)
  To: npostavs; +Cc: 24751

> From: npostavs@users.sourceforge.net
> Cc: 24751@debbugs.gnu.org
> Date: Mon, 14 Nov 2016 22:08:18 -0500
> 
> Actually, we should avoid increasing this limit if the stack wasn't
> increased, right?  Here's what I came up with, I think it doesn't cover
> Cygwin/Windows though.
> 
> diff --git c/src/emacs.c i/src/emacs.c
> index b74df21..d4655c8 100644
> --- c/src/emacs.c
> +++ i/src/emacs.c
> @@ -831,8 +831,8 @@ main (int argc, char **argv)
>  	 re_max_failures, then add 33% to cover the size of the
>  	 smaller stacks that regex.c successively allocates and
>  	 discards on its way to the maximum.  */
> -      int ratio = 20 * sizeof (char *);
> -      ratio += ratio / 3;
> +      int min_ratio = 20 * sizeof (char *);
> +      int ratio = min_ratio + min_ratio / 3;
>  
>        /* Extra space to cover what we're likely to use for other reasons.  */
>        int extra = 200000;
> @@ -869,6 +869,7 @@ main (int argc, char **argv)
>  
>        /* Don't let regex.c overflow the stack.  */
>        re_max_failures = lim < extra ? 0 : min (lim - extra, SIZE_MAX) / ratio;
> +      emacs_re_safe_alloca = re_max_failures * min_ratio;
>      }
>  #endif /* HAVE_SETRLIMIT and RLIMIT_STACK and not CYGWIN */

Right, but I have 2 comments:

  . we shouldn't set re_max_failures to zero if the amount of stack is
    less than 'extra', since in that case we will allocate the failure
    stack off the heap;
  . emacs_re_safe_alloca should have its minimum value MAX_ALLOCA, not
    zero, because SAFE_ALLOCA can still be used in regex.c, even
    though the failure stack will be malloc'ed.

Thanks.





^ permalink raw reply	[flat|nested] 22+ messages in thread

* bug#24751: 26.0.50; Regex stack overflow not detected properly (gets "Variable binding depth exceeds max-specpdl-size")
  2016-11-15 16:12             ` Eli Zaretskii
@ 2016-11-16  1:06               ` npostavs
  2016-11-16 16:25                 ` Eli Zaretskii
  0 siblings, 1 reply; 22+ messages in thread
From: npostavs @ 2016-11-16  1:06 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 24751

>> @@ -869,6 +869,7 @@ main (int argc, char **argv)
>>  
>>        /* Don't let regex.c overflow the stack.  */
>>        re_max_failures = lim < extra ? 0 : min (lim - extra, SIZE_MAX) / ratio;
>> +      emacs_re_safe_alloca = re_max_failures * min_ratio;
>>      }
>>  #endif /* HAVE_SETRLIMIT and RLIMIT_STACK and not CYGWIN */
>
>   . we shouldn't set re_max_failures to zero if the amount of stack is
>     less than 'extra', since in that case we will allocate the failure
>     stack off the heap;

Then what should we set it to?  Maybe we shouldn't modify it at all,
since the stack isn't actually a limiting factor?





^ permalink raw reply	[flat|nested] 22+ messages in thread

* bug#24751: 26.0.50; Regex stack overflow not detected properly (gets "Variable binding depth exceeds max-specpdl-size")
  2016-11-16  1:06               ` npostavs
@ 2016-11-16 16:25                 ` Eli Zaretskii
  2016-11-16 23:25                   ` npostavs
  0 siblings, 1 reply; 22+ messages in thread
From: Eli Zaretskii @ 2016-11-16 16:25 UTC (permalink / raw)
  To: npostavs; +Cc: 24751

> From: npostavs@users.sourceforge.net
> Cc: 24751@debbugs.gnu.org
> Date: Tue, 15 Nov 2016 20:06:29 -0500
> 
> >> @@ -869,6 +869,7 @@ main (int argc, char **argv)
> >>  
> >>        /* Don't let regex.c overflow the stack.  */
> >>        re_max_failures = lim < extra ? 0 : min (lim - extra, SIZE_MAX) / ratio;
> >> +      emacs_re_safe_alloca = re_max_failures * min_ratio;
> >>      }
> >>  #endif /* HAVE_SETRLIMIT and RLIMIT_STACK and not CYGWIN */
> >
> >   . we shouldn't set re_max_failures to zero if the amount of stack is
> >     less than 'extra', since in that case we will allocate the failure
> >     stack off the heap;
> 
> Then what should we set it to?  Maybe we shouldn't modify it at all,
> since the stack isn't actually a limiting factor?

Yes, I think this is the best solution.

Thanks.





^ permalink raw reply	[flat|nested] 22+ messages in thread

* bug#24751: 26.0.50; Regex stack overflow not detected properly (gets "Variable binding depth exceeds max-specpdl-size")
  2016-11-16 16:25                 ` Eli Zaretskii
@ 2016-11-16 23:25                   ` npostavs
  2016-11-17 16:21                     ` Eli Zaretskii
  0 siblings, 1 reply; 22+ messages in thread
From: npostavs @ 2016-11-16 23:25 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 24751

Eli Zaretskii <eliz@gnu.org> writes:

>> From: npostavs@users.sourceforge.net
>> Cc: 24751@debbugs.gnu.org
>> Date: Tue, 15 Nov 2016 20:06:29 -0500
>> 
>> >> @@ -869,6 +869,7 @@ main (int argc, char **argv)
>> >>  
>> >>        /* Don't let regex.c overflow the stack.  */
>> >>        re_max_failures = lim < extra ? 0 : min (lim - extra, SIZE_MAX) / ratio;
>> >> +      emacs_re_safe_alloca = re_max_failures * min_ratio;
>> >>      }
>> >>  #endif /* HAVE_SETRLIMIT and RLIMIT_STACK and not CYGWIN */
>> >
>> >   . we shouldn't set re_max_failures to zero if the amount of stack is
>> >     less than 'extra', since in that case we will allocate the failure
>> >     stack off the heap;
>> 
>> Then what should we set it to?  Maybe we shouldn't modify it at all,
>> since the stack isn't actually a limiting factor?
>
> Yes, I think this is the best solution.
>

One more question, is this comment (around line 1198) now obsolete?  (if
not, it sounds like we might still have some serious problems)

/* Define MATCH_MAY_ALLOCATE unless we need to make sure that the
   searching and matching functions should not call alloca.  On some
   systems, alloca is implemented in terms of malloc, and if we're
   using the relocating allocator routines, then malloc could cause a
   relocation, which might (if the strings being searched are in the
   ralloc heap) shift the data out from underneath the regexp
   routines.

   Here's another reason to avoid allocation: Emacs
   processes input from X in a signal handler; processing X input may
   call malloc; if input arrives while a matching routine is calling
   malloc, then we're scrod.  But Emacs can't just block input while
   calling matching routines; then we don't notice interrupts when
   they come in.  So, Emacs blocks input around all regexp calls
   except the matching calls, which it leaves unprotected, in the
   faith that they will not malloc.  */

Also this one (around line 430)

/* Should we use malloc or alloca?  If REGEX_MALLOC is not defined, we
   use `alloca' instead of `malloc'.  This is because using malloc in
   re_search* or re_match* could cause memory leaks when C-g is used in
   Emacs; also, malloc is slower and causes storage fragmentation.  On
   the other hand, malloc is more portable, and easier to debug.

   Because we sometimes use alloca, some routines have to be macros,
   not functions -- `alloca'-allocated space disappears at the end of the
   function it is called in.  */






^ permalink raw reply	[flat|nested] 22+ messages in thread

* bug#24751: 26.0.50; Regex stack overflow not detected properly (gets "Variable binding depth exceeds max-specpdl-size")
  2016-11-16 23:25                   ` npostavs
@ 2016-11-17 16:21                     ` Eli Zaretskii
  2016-11-19 10:02                       ` Eli Zaretskii
                                         ` (2 more replies)
  0 siblings, 3 replies; 22+ messages in thread
From: Eli Zaretskii @ 2016-11-17 16:21 UTC (permalink / raw)
  To: npostavs; +Cc: 24751

> From: npostavs@users.sourceforge.net
> Cc: 24751@debbugs.gnu.org
> Date: Wed, 16 Nov 2016 18:25:22 -0500
> 
> One more question, is this comment (around line 1198) now obsolete?  (if
> not, it sounds like we might still have some serious problems)
> 
> /* Define MATCH_MAY_ALLOCATE unless we need to make sure that the
>    searching and matching functions should not call alloca.  On some
>    systems, alloca is implemented in terms of malloc, and if we're
>    using the relocating allocator routines, then malloc could cause a
>    relocation, which might (if the strings being searched are in the
>    ralloc heap) shift the data out from underneath the regexp
>    routines.
> 
>    Here's another reason to avoid allocation: Emacs
>    processes input from X in a signal handler; processing X input may
>    call malloc; if input arrives while a matching routine is calling
>    malloc, then we're scrod.  But Emacs can't just block input while
>    calling matching routines; then we don't notice interrupts when
>    they come in.  So, Emacs blocks input around all regexp calls
>    except the matching calls, which it leaves unprotected, in the
>    faith that they will not malloc.  */

The second part is obsolete: we no longer do anything significant from
a signal handler, we just set a flag.

The first part is not obsolete, but its reasoning is backwards:
SAFE_ALLOCA indeed can call malloc, but it could only cause relocation
if REGEX_MALLOC is defined (and ralloc.c is compiled in).  And when
you define REGEX_MALLOC, MATCH_MAY_ALLOCATE is undefined.  So the text
there should be revised.

> Also this one (around line 430)
> 
> /* Should we use malloc or alloca?  If REGEX_MALLOC is not defined, we
>    use `alloca' instead of `malloc'.  This is because using malloc in
>    re_search* or re_match* could cause memory leaks when C-g is used in
>    Emacs; also, malloc is slower and causes storage fragmentation.  On
>    the other hand, malloc is more portable, and easier to debug.
> 
>    Because we sometimes use alloca, some routines have to be macros,
>    not functions -- `alloca'-allocated space disappears at the end of the
>    function it is called in.  */

This is correct AFAIU, but perhaps it's worth adding that even if
SAFE_ALLOCA decides to call malloc, it takes care to set up
unwind-protect scheme that will free the allocated memory upon C-g (or
any other throw-type op), and avoid leaking memory.

Thanks.





^ permalink raw reply	[flat|nested] 22+ messages in thread

* bug#24751: 26.0.50; Regex stack overflow not detected properly (gets "Variable binding depth exceeds max-specpdl-size")
  2016-11-17 16:21                     ` Eli Zaretskii
@ 2016-11-19 10:02                       ` Eli Zaretskii
  2017-01-01 18:33                       ` npostavs
  2017-01-02  4:49                       ` npostavs
  2 siblings, 0 replies; 22+ messages in thread
From: Eli Zaretskii @ 2016-11-19 10:02 UTC (permalink / raw)
  To: npostavs; +Cc: 24751

One other comment: the value of 'extra' in emacs.c looks too small to
me.  If we want to safely allocate the failure stack off the run-time
C stack, we should make 'extra' large enough to cover a typical GC,
which can take as many as 30K stack frames.  So I'd enlarge 'extra' to
be something like 1500000.





^ permalink raw reply	[flat|nested] 22+ messages in thread

* bug#24751: 26.0.50; Regex stack overflow not detected properly (gets "Variable binding depth exceeds max-specpdl-size")
  2016-11-17 16:21                     ` Eli Zaretskii
  2016-11-19 10:02                       ` Eli Zaretskii
@ 2017-01-01 18:33                       ` npostavs
  2017-01-01 18:41                         ` Eli Zaretskii
  2017-01-02  4:49                       ` npostavs
  2 siblings, 1 reply; 22+ messages in thread
From: npostavs @ 2017-01-01 18:33 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 24751

Eli Zaretskii <eliz@gnu.org> writes:
>> 
>> /* Define MATCH_MAY_ALLOCATE unless we need to make sure that the
>>    searching and matching functions should not call alloca.  On some
>>    systems, alloca is implemented in terms of malloc, and if we're
>>    using the relocating allocator routines, then malloc could cause a
>>    relocation, which might (if the strings being searched are in the
>>    ralloc heap) shift the data out from underneath the regexp
>>    routines.
>> 
>>    [...]
>
> The first part is not obsolete, but its reasoning is backwards:
> SAFE_ALLOCA indeed can call malloc, but it could only cause relocation
> if REGEX_MALLOC is defined (and ralloc.c is compiled in).  And when
> you define REGEX_MALLOC, MATCH_MAY_ALLOCATE is undefined.  So the text
> there should be revised.

Is there ever any case where REGEX_MALLOC is defined?  I can't see where
it happens.  I don't understand why you say relocation is dependent on
REGEX_MALLOC, I thought only REL_ALLOC affects that.

And since we added r_alloc_inhibit_buffer_relocation around the regex
calls, aren't all these concerns about relocation obsolete?





^ permalink raw reply	[flat|nested] 22+ messages in thread

* bug#24751: 26.0.50; Regex stack overflow not detected properly (gets "Variable binding depth exceeds max-specpdl-size")
  2017-01-01 18:33                       ` npostavs
@ 2017-01-01 18:41                         ` Eli Zaretskii
  2017-01-01 18:57                           ` npostavs
  0 siblings, 1 reply; 22+ messages in thread
From: Eli Zaretskii @ 2017-01-01 18:41 UTC (permalink / raw)
  To: npostavs; +Cc: 24751

> From: npostavs@users.sourceforge.net
> Cc: 24751@debbugs.gnu.org
> Date: Sun, 01 Jan 2017 13:33:35 -0500
> 
> Eli Zaretskii <eliz@gnu.org> writes:
> >> 
> >> /* Define MATCH_MAY_ALLOCATE unless we need to make sure that the
> >>    searching and matching functions should not call alloca.  On some
> >>    systems, alloca is implemented in terms of malloc, and if we're
> >>    using the relocating allocator routines, then malloc could cause a
> >>    relocation, which might (if the strings being searched are in the
> >>    ralloc heap) shift the data out from underneath the regexp
> >>    routines.
> >> 
> >>    [...]
> >
> > The first part is not obsolete, but its reasoning is backwards:
> > SAFE_ALLOCA indeed can call malloc, but it could only cause relocation
> > if REGEX_MALLOC is defined (and ralloc.c is compiled in).  And when
> > you define REGEX_MALLOC, MATCH_MAY_ALLOCATE is undefined.  So the text
> > there should be revised.
> 
> Is there ever any case where REGEX_MALLOC is defined?  I can't see where
> it happens.

I don't understand the question.  You can compile regex.c with the
"-DREGEX_MALLOC" option whenever you like.  We don't do that, but as
long as the code which supports that is in regex.c, the comment goes
with it.

> I don't understand why you say relocation is dependent on
> REGEX_MALLOC, I thought only REL_ALLOC affects that.

REL_ALLOC determines whether ralloc.c is compiled in, which I
mentioned above.

> And since we added r_alloc_inhibit_buffer_relocation around the regex
> calls, aren't all these concerns about relocation obsolete?

The calls to r_alloc_inhibit_buffer_relocation are outside of regex.c,
so the comments in regex.c don't know anything about that.





^ permalink raw reply	[flat|nested] 22+ messages in thread

* bug#24751: 26.0.50; Regex stack overflow not detected properly (gets "Variable binding depth exceeds max-specpdl-size")
  2017-01-01 18:41                         ` Eli Zaretskii
@ 2017-01-01 18:57                           ` npostavs
  2017-01-01 20:06                             ` Eli Zaretskii
  0 siblings, 1 reply; 22+ messages in thread
From: npostavs @ 2017-01-01 18:57 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 24751

Eli Zaretskii <eliz@gnu.org> writes:

>> From: npostavs@users.sourceforge.net
>> Cc: 24751@debbugs.gnu.org
>> Date: Sun, 01 Jan 2017 13:33:35 -0500
>> 
>> Eli Zaretskii <eliz@gnu.org> writes:
>> >> 
>> >> /* Define MATCH_MAY_ALLOCATE unless we need to make sure that the
>> >>    searching and matching functions should not call alloca.  On some
>> >>    systems, alloca is implemented in terms of malloc, and if we're
>> >>    using the relocating allocator routines, then malloc could cause a
>> >>    relocation, which might (if the strings being searched are in the
>> >>    ralloc heap) shift the data out from underneath the regexp
>> >>    routines.
>> >> 
>> >>    [...]
>> >
>> > The first part is not obsolete, but its reasoning is backwards:
>> > SAFE_ALLOCA indeed can call malloc, but it could only cause relocation
>> > if REGEX_MALLOC is defined (and ralloc.c is compiled in).  And when
>> > you define REGEX_MALLOC, MATCH_MAY_ALLOCATE is undefined.  So the text
>> > there should be revised.
>> 
>> Is there ever any case where REGEX_MALLOC is defined?  I can't see where
>> it happens.
>
> I don't understand the question.  You can compile regex.c with the
> "-DREGEX_MALLOC" option whenever you like.  We don't do that,
                                              ^^^^^^^^^^^^^^^^

Thanks, that's what I was wondering about in my question.

>
>> I don't understand why you say relocation is dependent on
>> REGEX_MALLOC, I thought only REL_ALLOC affects that.
>
> REL_ALLOC determines whether ralloc.c is compiled in, which I
> mentioned above.

But if REL_ALLOC is defined, then SAFE_ALLOCA could cause relocation
(via malloc) regardless of whether REGEX_MALLOC is defined or not, no?





^ permalink raw reply	[flat|nested] 22+ messages in thread

* bug#24751: 26.0.50; Regex stack overflow not detected properly (gets "Variable binding depth exceeds max-specpdl-size")
  2017-01-01 18:57                           ` npostavs
@ 2017-01-01 20:06                             ` Eli Zaretskii
  0 siblings, 0 replies; 22+ messages in thread
From: Eli Zaretskii @ 2017-01-01 20:06 UTC (permalink / raw)
  To: npostavs; +Cc: 24751

> From: npostavs@users.sourceforge.net
> Cc: 24751@debbugs.gnu.org
> Date: Sun, 01 Jan 2017 13:57:05 -0500
> 
> >> I don't understand why you say relocation is dependent on
> >> REGEX_MALLOC, I thought only REL_ALLOC affects that.
> >
> > REL_ALLOC determines whether ralloc.c is compiled in, which I
> > mentioned above.
> 
> But if REL_ALLOC is defined, then SAFE_ALLOCA could cause relocation
> (via malloc) regardless of whether REGEX_MALLOC is defined or not, no?

Relocation as side effect of calling malloc only happens with buffer
text.  This is not what the comment in question alludes to.  It
alludes to this:

  /* Define how to allocate the failure stack.  */

  #if defined REL_ALLOC && defined REGEX_MALLOC

  # define REGEX_ALLOCATE_STACK(size)				\
    r_alloc (&failure_stack_ptr, (size))
  # define REGEX_REALLOCATE_STACK(source, osize, nsize)		\
    r_re_alloc (&failure_stack_ptr, (nsize))
  # define REGEX_FREE_STACK(ptr)					\
    r_alloc_free (&failure_stack_ptr)

  #else /* not using relocating allocator */

  # define REGEX_ALLOCATE_STACK(size) REGEX_ALLOCATE (size)
  # define REGEX_REALLOCATE_STACK(source, o, n) REGEX_REALLOCATE (source, o, n)
  # define REGEX_FREE_STACK(ptr) REGEX_FREE (ptr)

  #endif /* not using relocating allocator */

This calls ralloc.c functions directly for allocating/reallocating the
failure stack, when both REL_ALLOC and REGEX_MALLOC are defined.  So
the relocation in question is that of the failure stack, which won't
happen if we call malloc, even if REL_ALLOC is defined, because only
buffer text can be relocated when ralloc.c is called from malloc.





^ permalink raw reply	[flat|nested] 22+ messages in thread

* bug#24751: 26.0.50; Regex stack overflow not detected properly (gets "Variable binding depth exceeds max-specpdl-size")
  2016-11-17 16:21                     ` Eli Zaretskii
  2016-11-19 10:02                       ` Eli Zaretskii
  2017-01-01 18:33                       ` npostavs
@ 2017-01-02  4:49                       ` npostavs
  2017-01-02 15:24                         ` Eli Zaretskii
  2 siblings, 1 reply; 22+ messages in thread
From: npostavs @ 2017-01-02  4:49 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 24751

[-- Attachment #1: Type: text/plain, Size: 994 bytes --]

Eli Zaretskii <eliz@gnu.org> writes:

>> 
>> /* Define MATCH_MAY_ALLOCATE unless we need to make sure that the
>>    searching and matching functions should not call alloca.  On some
>>    systems, alloca is implemented in terms of malloc, and if we're
>>    using the relocating allocator routines, then malloc could cause a
>>    relocation, which might (if the strings being searched are in the
>>    ralloc heap) shift the data out from underneath the regexp
>>    routines.
>
>
> The first part is not obsolete, but its reasoning is backwards:
> SAFE_ALLOCA indeed can call malloc, but it could only cause relocation
> if REGEX_MALLOC is defined (and ralloc.c is compiled in).  And when
> you define REGEX_MALLOC, MATCH_MAY_ALLOCATE is undefined.  So the text
> there should be revised.

Everything you've said makes sense after your last message, but I'm
still unable to put it together and come up with a revised comment.
Could you make a suggestion?  Here are the rest of the changes.


[-- Attachment #2: patch --]
[-- Type: text/plain, Size: 8503 bytes --]

From 60e43d62735b212738584da0631c8efc768084c5 Mon Sep 17 00:00:00 2001
From: Noam Postavsky <npostavs@gmail.com>
Date: Sun, 1 Jan 2017 14:09:13 -0500
Subject: [PATCH v1] Use expanded stack during regex matches

While the stack is increased in main(), to allow the regex stack
allocation to use alloca we also need to modify regex.c to actually take
advantage of the increased stack, and not limit stack allocations to
SAFE_ALLOCA bytes.

* src/regex.c (MATCH_MAY_ALLOCATE): Remove obsolete comment about
allocations in signal handlers which no longer happens.
(emacs_re_safe_alloca): New variable.
(REGEX_USE_SAFE_ALLOCA): Use it as the limit of stack allocation instead
of MAX_ALLOCA.
(emacs_re_max_failures): Rename from `re_max_failures' to avoid
confusion the glibc's `re_max_failures'.
* src/emacs.c (main): Increase the amount of fixed 'extra' bytes we add
to the stack.  Instead of changing emacs_re_max_failures based on the
new stack size, just change emacs_re_safe_alloca; emacs_re_max_failures
remains constant regardless, since if we run out stack space SAFE_ALLOCA
will fall back to heap allocation.
---
 src/emacs.c | 21 ++++++++++++---------
 src/regex.c | 44 ++++++++++++++++++++++----------------------
 src/regex.h |  7 ++++++-
 3 files changed, 40 insertions(+), 32 deletions(-)

diff --git a/src/emacs.c b/src/emacs.c
index ae29e9a..cb6b503 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -831,14 +831,16 @@ main (int argc, char **argv)
       rlim_t lim = rlim.rlim_cur;
 
       /* Approximate the amount regex.c needs per unit of
-	 re_max_failures, then add 33% to cover the size of the
+	 emacs_re_max_failures, then add 33% to cover the size of the
 	 smaller stacks that regex.c successively allocates and
 	 discards on its way to the maximum.  */
-      int ratio = 20 * sizeof (char *);
-      ratio += ratio / 3;
+      int min_ratio = 20 * sizeof (char *);
+      int ratio = min_ratio + min_ratio / 3;
 
-      /* Extra space to cover what we're likely to use for other reasons.  */
-      int extra = 200000;
+      /* Extra space to cover what we're likely to use for other
+         reasons.  For example, a typical GC might take 30K stack
+         frames.  */
+      int extra = (30 * 1000) * 50;
 
       bool try_to_grow_stack = true;
 #ifndef CANNOT_DUMP
@@ -847,7 +849,7 @@ main (int argc, char **argv)
 
       if (try_to_grow_stack)
 	{
-	  rlim_t newlim = re_max_failures * ratio + extra;
+	  rlim_t newlim = emacs_re_max_failures * ratio + extra;
 
 	  /* Round the new limit to a page boundary; this is needed
 	     for Darwin kernel 15.4.0 (see Bug#23622) and perhaps
@@ -869,9 +871,10 @@ main (int argc, char **argv)
 		lim = newlim;
 	    }
 	}
-
-      /* Don't let regex.c overflow the stack.  */
-      re_max_failures = lim < extra ? 0 : min (lim - extra, SIZE_MAX) / ratio;
+      /* Let regex.c use more stack, if available.  */
+      emacs_re_safe_alloca = max
+        (min (lim - extra, SIZE_MAX) * (min_ratio / ratio),
+         MAX_ALLOCA);
     }
 #endif /* HAVE_SETRLIMIT and RLIMIT_STACK and not CYGWIN */
 
diff --git a/src/regex.c b/src/regex.c
index a2d2c52..adf2fa1 100644
--- a/src/regex.c
+++ b/src/regex.c
@@ -430,9 +430,12 @@ init_syntax_once (void)
 \f
 /* Should we use malloc or alloca?  If REGEX_MALLOC is not defined, we
    use `alloca' instead of `malloc'.  This is because using malloc in
-   re_search* or re_match* could cause memory leaks when C-g is used in
-   Emacs; also, malloc is slower and causes storage fragmentation.  On
-   the other hand, malloc is more portable, and easier to debug.
+   re_search* or re_match* could cause memory leaks when C-g is used
+   in Emacs (note that SAFE_ALLOCA could also call malloc, but does so
+   via `record_xmalloc' which uses `unwind_protect' to ensure the
+   memory is freed even in case of non-local exits); also, malloc is
+   slower and causes storage fragmentation.  On the other hand, malloc
+   is more portable, and easier to debug.
 
    Because we sometimes use alloca, some routines have to be macros,
    not functions -- `alloca'-allocated space disappears at the end of the
@@ -447,7 +450,13 @@ init_syntax_once (void)
 #else /* not REGEX_MALLOC  */
 
 # ifdef emacs
-#  define REGEX_USE_SAFE_ALLOCA USE_SAFE_ALLOCA
+/* This may be adjusted in main(), if the stack is successfully grown.  */
+ptrdiff_t emacs_re_safe_alloca = MAX_ALLOCA;
+/* Like USE_SAFE_ALLOCA, but use emacs_re_safe_alloca.  */
+#  define REGEX_USE_SAFE_ALLOCA                                        \
+  ptrdiff_t sa_avail = emacs_re_safe_alloca;                           \
+  ptrdiff_t sa_count = SPECPDL_INDEX (); bool sa_must_free = false
+
 #  define REGEX_SAFE_FREE() SAFE_FREE ()
 #  define REGEX_ALLOCATE SAFE_ALLOCA
 # else
@@ -1203,16 +1212,7 @@ WEAK_ALIAS (__re_set_syntax, re_set_syntax)
    using the relocating allocator routines, then malloc could cause a
    relocation, which might (if the strings being searched are in the
    ralloc heap) shift the data out from underneath the regexp
-   routines.
-
-   Here's another reason to avoid allocation: Emacs
-   processes input from X in a signal handler; processing X input may
-   call malloc; if input arrives while a matching routine is calling
-   malloc, then we're scrod.  But Emacs can't just block input while
-   calling matching routines; then we don't notice interrupts when
-   they come in.  So, Emacs blocks input around all regexp calls
-   except the matching calls, which it leaves unprotected, in the
-   faith that they will not malloc.  */
+   routines.  */
 
 /* Normally, this is fine.  */
 #define MATCH_MAY_ALLOCATE
@@ -1249,9 +1249,9 @@ WEAK_ALIAS (__re_set_syntax, re_set_syntax)
    whose default stack limit is 2mb.  In order for a larger
    value to work reliably, you have to try to make it accord
    with the process stack limit.  */
-size_t re_max_failures = 40000;
+size_t emacs_re_max_failures = 40000;
 # else
-size_t re_max_failures = 4000;
+size_t emacs_re_max_failures = 4000;
 # endif
 
 union fail_stack_elt
@@ -1304,7 +1304,7 @@ WEAK_ALIAS (__re_set_syntax, re_set_syntax)
 
 
 /* Double the size of FAIL_STACK, up to a limit
-   which allows approximately `re_max_failures' items.
+   which allows approximately `emacs_re_max_failures' items.
 
    Return 1 if succeeds, and 0 if either ran out of memory
    allocating space for it or it was already too large.
@@ -1319,19 +1319,19 @@ WEAK_ALIAS (__re_set_syntax, re_set_syntax)
 #define FAIL_STACK_GROWTH_FACTOR 4
 
 #define GROW_FAIL_STACK(fail_stack)					\
-  (((fail_stack).size >= re_max_failures * TYPICAL_FAILURE_SIZE)        \
+  (((fail_stack).size >= emacs_re_max_failures * TYPICAL_FAILURE_SIZE)        \
    ? 0									\
    : ((fail_stack).stack						\
       = REGEX_REALLOCATE_STACK ((fail_stack).stack,			\
 	  (fail_stack).size * sizeof (fail_stack_elt_t),		\
-          min (re_max_failures * TYPICAL_FAILURE_SIZE,                  \
+          min (emacs_re_max_failures * TYPICAL_FAILURE_SIZE,                  \
                ((fail_stack).size * FAIL_STACK_GROWTH_FACTOR))          \
           * sizeof (fail_stack_elt_t)),                                 \
 									\
       (fail_stack).stack == NULL					\
       ? 0								\
       : ((fail_stack).size						\
-         = (min (re_max_failures * TYPICAL_FAILURE_SIZE,                \
+         = (min (emacs_re_max_failures * TYPICAL_FAILURE_SIZE,                \
                  ((fail_stack).size * FAIL_STACK_GROWTH_FACTOR))),      \
 	 1)))
 
@@ -3638,9 +3638,9 @@ regex_compile (const_re_char *pattern, size_t size,
   {
     int num_regs = bufp->re_nsub + 1;
 
-    if (fail_stack.size < re_max_failures * TYPICAL_FAILURE_SIZE)
+    if (fail_stack.size < emacs_re_max_failures * TYPICAL_FAILURE_SIZE)
       {
-	fail_stack.size = re_max_failures * TYPICAL_FAILURE_SIZE;
+	fail_stack.size = emacs_re_max_failures * TYPICAL_FAILURE_SIZE;
 	falk_stack.stack = realloc (fail_stack.stack,
 				    fail_stack.size * sizeof *falk_stack.stack);
       }
diff --git a/src/regex.h b/src/regex.h
index 34c9929..1d439de 100644
--- a/src/regex.h
+++ b/src/regex.h
@@ -186,7 +186,12 @@
 #endif
 
 /* Roughly the maximum number of failure points on the stack.  */
-extern size_t re_max_failures;
+extern size_t emacs_re_max_failures;
+
+#ifdef emacs
+/* Amount of memory that we can safely stack allocate.  */
+extern ptrdiff_t emacs_re_safe_alloca;
+#endif
 
 \f
 /* Define combinations of the above bits for the standard possibilities.
-- 
2.9.3


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* bug#24751: 26.0.50; Regex stack overflow not detected properly (gets "Variable binding depth exceeds max-specpdl-size")
  2017-01-02  4:49                       ` npostavs
@ 2017-01-02 15:24                         ` Eli Zaretskii
  2017-01-02 18:30                           ` npostavs
  0 siblings, 1 reply; 22+ messages in thread
From: Eli Zaretskii @ 2017-01-02 15:24 UTC (permalink / raw)
  To: npostavs; +Cc: 24751

> From: npostavs@users.sourceforge.net
> Cc: 24751@debbugs.gnu.org
> Date: Sun, 01 Jan 2017 23:49:46 -0500
> 
> Everything you've said makes sense after your last message, but I'm
> still unable to put it together and come up with a revised comment.
> Could you make a suggestion?

How about the below?

--- src/regex.c~0	2016-12-11 06:39:19.000000000 +0200
+++ src/regex.c	2017-01-02 12:40:44.266517100 +0200
@@ -1195,24 +1195,28 @@
     gettext_noop ("Range striding over charsets") /* REG_ERANGEX  */
   };
 \f
-/* Avoiding alloca during matching, to placate r_alloc.  */
+/* Whether to allocate memory during matching.  */
 
-/* Define MATCH_MAY_ALLOCATE unless we need to make sure that the
-   searching and matching functions should not call alloca.  On some
-   systems, alloca is implemented in terms of malloc, and if we're
-   using the relocating allocator routines, then malloc could cause a
-   relocation, which might (if the strings being searched are in the
-   ralloc heap) shift the data out from underneath the regexp
-   routines.
-
-   Here's another reason to avoid allocation: Emacs
-   processes input from X in a signal handler; processing X input may
-   call malloc; if input arrives while a matching routine is calling
-   malloc, then we're scrod.  But Emacs can't just block input while
-   calling matching routines; then we don't notice interrupts when
-   they come in.  So, Emacs blocks input around all regexp calls
-   except the matching calls, which it leaves unprotected, in the
-   faith that they will not malloc.  */
+/* Define MATCH_MAY_ALLOCATE to allow the searching and matching
+   functions allocate memory for the failure stack and registers.
+   Normally should be defined, because otherwise searching and
+   matching routines will have much smaller memory resources at their
+   disposal, and therefore might fail to handle complex regexps.
+   Therefore undefine MATCH_MAY_ALLOCATE only in the following
+   exceptional situations:
+
+   . When running on a system where memory is at premium.
+   . When alloca cannot be used at all, perhaps due to bugs in
+     its implementation, or its being unavailable, or due to a
+     very small stack size.  This requires to define REGEX_MALLOC
+     to use malloc instead, which in turn could lead to memory
+     leaks if search is interrupted by a signal.  (For these
+     reasons, defining REGEX_MALLOC when building Emacs
+     automatically undefines MATCH_MAY_ALLOCATE, but outside
+     Emacs you may not care about memory leaks.)  If you want to
+     prevent the memory leaks, undefine MATCH_MAY_ALLOCATE.
+   . When code that calls the searching and matching functions
+     cannot allow memory allocation, for whatever reasons.  */
 
 /* Normally, this is fine.  */
 #define MATCH_MAY_ALLOCATE





^ permalink raw reply	[flat|nested] 22+ messages in thread

* bug#24751: 26.0.50; Regex stack overflow not detected properly (gets "Variable binding depth exceeds max-specpdl-size")
  2017-01-02 15:24                         ` Eli Zaretskii
@ 2017-01-02 18:30                           ` npostavs
  2017-01-02 19:22                             ` Eli Zaretskii
  0 siblings, 1 reply; 22+ messages in thread
From: npostavs @ 2017-01-02 18:30 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 24751

[-- Attachment #1: Type: text/plain, Size: 402 bytes --]

Eli Zaretskii <eliz@gnu.org> writes:

>> From: npostavs@users.sourceforge.net
>> Cc: 24751@debbugs.gnu.org
>> Date: Sun, 01 Jan 2017 23:49:46 -0500
>> 
>> Everything you've said makes sense after your last message, but I'm
>> still unable to put it together and come up with a revised comment.
>> Could you make a suggestion?
>
> How about the below?

Looks good, I've incorporated it into the patch:


[-- Attachment #2: patch --]
[-- Type: text/plain, Size: 2151 bytes --]

From 188801f8e017f0702cbb24390e4f88b3d0da18ff Mon Sep 17 00:00:00 2001
From: Noam Postavsky <npostavs@gmail.com>
Date: Sat, 5 Nov 2016 16:51:53 -0400
Subject: [PATCH v3 1/2] Fix computation of regex stack limit

The regex stack limit was being computed as the number of stack entries,
whereas it was being compared with the current size as measured in
bytes.  This could cause indefinite looping when nearing the stack limit
if re_max_failures happened not to be a multiple of sizeof
fail_stack_elt_t (Bug #24751).

* src/regex.c (GROW_FAIL_STACK): Compute both current stack size and
limit as numbers of stack entries.
---
 src/regex.c | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/src/regex.c b/src/regex.c
index ae3fde8..a2d2c52 100644
--- a/src/regex.c
+++ b/src/regex.c
@@ -1319,23 +1319,20 @@ WEAK_ALIAS (__re_set_syntax, re_set_syntax)
 #define FAIL_STACK_GROWTH_FACTOR 4
 
 #define GROW_FAIL_STACK(fail_stack)					\
-  (((fail_stack).size * sizeof (fail_stack_elt_t)			\
-    >= re_max_failures * TYPICAL_FAILURE_SIZE)				\
+  (((fail_stack).size >= re_max_failures * TYPICAL_FAILURE_SIZE)        \
    ? 0									\
    : ((fail_stack).stack						\
       = REGEX_REALLOCATE_STACK ((fail_stack).stack,			\
 	  (fail_stack).size * sizeof (fail_stack_elt_t),		\
-	  min (re_max_failures * TYPICAL_FAILURE_SIZE,			\
-	       ((fail_stack).size * sizeof (fail_stack_elt_t)		\
-		* FAIL_STACK_GROWTH_FACTOR))),				\
+          min (re_max_failures * TYPICAL_FAILURE_SIZE,                  \
+               ((fail_stack).size * FAIL_STACK_GROWTH_FACTOR))          \
+          * sizeof (fail_stack_elt_t)),                                 \
 									\
       (fail_stack).stack == NULL					\
       ? 0								\
       : ((fail_stack).size						\
-	 = (min (re_max_failures * TYPICAL_FAILURE_SIZE,		\
-		 ((fail_stack).size * sizeof (fail_stack_elt_t)		\
-		  * FAIL_STACK_GROWTH_FACTOR))				\
-	    / sizeof (fail_stack_elt_t)),				\
+         = (min (re_max_failures * TYPICAL_FAILURE_SIZE,                \
+                 ((fail_stack).size * FAIL_STACK_GROWTH_FACTOR))),      \
 	 1)))
 
 
-- 
2.9.3


[-- Attachment #3: patch --]
[-- Type: text/plain, Size: 10273 bytes --]

From 76656125620b442c4895c8460a0fe7c5298b3fa6 Mon Sep 17 00:00:00 2001
From: Noam Postavsky <npostavs@gmail.com>
Date: Sun, 1 Jan 2017 14:09:13 -0500
Subject: [PATCH v3 2/2] Use expanded stack during regex matches

While the stack is increased in main(), to allow the regex stack
allocation to use alloca we also need to modify regex.c to actually take
advantage of the increased stack, and not limit stack allocations to
SAFE_ALLOCA bytes.

* src/regex.c (MATCH_MAY_ALLOCATE): Remove obsolete comment about
allocations in signal handlers which no longer happens and correct
description about when and why MATCH_MAY_ALLOCATE should be defined.
(emacs_re_safe_alloca): New variable.
(REGEX_USE_SAFE_ALLOCA): Use it as the limit of stack allocation instead
of MAX_ALLOCA.
(emacs_re_max_failures): Rename from `re_max_failures' to avoid
confusion with glibc's `re_max_failures'.
* src/emacs.c (main): Increase the amount of fixed 'extra' bytes we add
to the stack.  Instead of changing emacs_re_max_failures based on the
new stack size, just change emacs_re_safe_alloca; emacs_re_max_failures
remains constant regardless, since if we run out stack space SAFE_ALLOCA
will fall back to heap allocation.

Co-authored-by: Eli Zaretskii <eliz@gnu.org>
---
 src/emacs.c | 22 +++++++++++--------
 src/regex.c | 73 ++++++++++++++++++++++++++++++++++++-------------------------
 src/regex.h |  7 +++++-
 3 files changed, 62 insertions(+), 40 deletions(-)

diff --git a/src/emacs.c b/src/emacs.c
index ae29e9a..28b395c 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -831,14 +831,16 @@ main (int argc, char **argv)
       rlim_t lim = rlim.rlim_cur;
 
       /* Approximate the amount regex.c needs per unit of
-	 re_max_failures, then add 33% to cover the size of the
+	 emacs_re_max_failures, then add 33% to cover the size of the
 	 smaller stacks that regex.c successively allocates and
 	 discards on its way to the maximum.  */
-      int ratio = 20 * sizeof (char *);
-      ratio += ratio / 3;
+      int min_ratio = 20 * sizeof (char *);
+      int ratio = min_ratio + min_ratio / 3;
 
-      /* Extra space to cover what we're likely to use for other reasons.  */
-      int extra = 200000;
+      /* Extra space to cover what we're likely to use for other
+         reasons.  For example, a typical GC might take 30K stack
+         frames.  */
+      int extra = (30 * 1000) * 50;
 
       bool try_to_grow_stack = true;
 #ifndef CANNOT_DUMP
@@ -847,7 +849,7 @@ main (int argc, char **argv)
 
       if (try_to_grow_stack)
 	{
-	  rlim_t newlim = re_max_failures * ratio + extra;
+	  rlim_t newlim = emacs_re_max_failures * ratio + extra;
 
 	  /* Round the new limit to a page boundary; this is needed
 	     for Darwin kernel 15.4.0 (see Bug#23622) and perhaps
@@ -869,9 +871,11 @@ main (int argc, char **argv)
 		lim = newlim;
 	    }
 	}
-
-      /* Don't let regex.c overflow the stack.  */
-      re_max_failures = lim < extra ? 0 : min (lim - extra, SIZE_MAX) / ratio;
+      /* If the stack is big enough, let regex.c more of it before
+         falling back to heap allocation.  */
+      emacs_re_safe_alloca = max
+        (min (lim - extra, SIZE_MAX) * (min_ratio / ratio),
+         MAX_ALLOCA);
     }
 #endif /* HAVE_SETRLIMIT and RLIMIT_STACK and not CYGWIN */
 
diff --git a/src/regex.c b/src/regex.c
index a2d2c52..5ebcda1 100644
--- a/src/regex.c
+++ b/src/regex.c
@@ -430,9 +430,12 @@ init_syntax_once (void)
 \f
 /* Should we use malloc or alloca?  If REGEX_MALLOC is not defined, we
    use `alloca' instead of `malloc'.  This is because using malloc in
-   re_search* or re_match* could cause memory leaks when C-g is used in
-   Emacs; also, malloc is slower and causes storage fragmentation.  On
-   the other hand, malloc is more portable, and easier to debug.
+   re_search* or re_match* could cause memory leaks when C-g is used
+   in Emacs (note that SAFE_ALLOCA could also call malloc, but does so
+   via `record_xmalloc' which uses `unwind_protect' to ensure the
+   memory is freed even in case of non-local exits); also, malloc is
+   slower and causes storage fragmentation.  On the other hand, malloc
+   is more portable, and easier to debug.
 
    Because we sometimes use alloca, some routines have to be macros,
    not functions -- `alloca'-allocated space disappears at the end of the
@@ -447,7 +450,13 @@ init_syntax_once (void)
 #else /* not REGEX_MALLOC  */
 
 # ifdef emacs
-#  define REGEX_USE_SAFE_ALLOCA USE_SAFE_ALLOCA
+/* This may be adjusted in main(), if the stack is successfully grown.  */
+ptrdiff_t emacs_re_safe_alloca = MAX_ALLOCA;
+/* Like USE_SAFE_ALLOCA, but use emacs_re_safe_alloca.  */
+#  define REGEX_USE_SAFE_ALLOCA                                        \
+  ptrdiff_t sa_avail = emacs_re_safe_alloca;                           \
+  ptrdiff_t sa_count = SPECPDL_INDEX (); bool sa_must_free = false
+
 #  define REGEX_SAFE_FREE() SAFE_FREE ()
 #  define REGEX_ALLOCATE SAFE_ALLOCA
 # else
@@ -1195,24 +1204,28 @@ WEAK_ALIAS (__re_set_syntax, re_set_syntax)
     gettext_noop ("Range striding over charsets") /* REG_ERANGEX  */
   };
 \f
-/* Avoiding alloca during matching, to placate r_alloc.  */
-
-/* Define MATCH_MAY_ALLOCATE unless we need to make sure that the
-   searching and matching functions should not call alloca.  On some
-   systems, alloca is implemented in terms of malloc, and if we're
-   using the relocating allocator routines, then malloc could cause a
-   relocation, which might (if the strings being searched are in the
-   ralloc heap) shift the data out from underneath the regexp
-   routines.
-
-   Here's another reason to avoid allocation: Emacs
-   processes input from X in a signal handler; processing X input may
-   call malloc; if input arrives while a matching routine is calling
-   malloc, then we're scrod.  But Emacs can't just block input while
-   calling matching routines; then we don't notice interrupts when
-   they come in.  So, Emacs blocks input around all regexp calls
-   except the matching calls, which it leaves unprotected, in the
-   faith that they will not malloc.  */
+/* Whether to allocate memory during matching.  */
+
+/* Define MATCH_MAY_ALLOCATE to allow the searching and matching
+   functions allocate memory for the failure stack and registers.
+   Normally should be defined, because otherwise searching and
+   matching routines will have much smaller memory resources at their
+   disposal, and therefore might fail to handle complex regexps.
+   Therefore undefine MATCH_MAY_ALLOCATE only in the following
+   exceptional situations:
+
+   . When running on a system where memory is at premium.
+   . When alloca cannot be used at all, perhaps due to bugs in
+     its implementation, or its being unavailable, or due to a
+     very small stack size.  This requires to define REGEX_MALLOC
+     to use malloc instead, which in turn could lead to memory
+     leaks if search is interrupted by a signal.  (For these
+     reasons, defining REGEX_MALLOC when building Emacs
+     automatically undefines MATCH_MAY_ALLOCATE, but outside
+     Emacs you may not care about memory leaks.)  If you want to
+     prevent the memory leaks, undefine MATCH_MAY_ALLOCATE.
+   . When code that calls the searching and matching functions
+     cannot allow memory allocation, for whatever reasons.  */
 
 /* Normally, this is fine.  */
 #define MATCH_MAY_ALLOCATE
@@ -1249,9 +1262,9 @@ WEAK_ALIAS (__re_set_syntax, re_set_syntax)
    whose default stack limit is 2mb.  In order for a larger
    value to work reliably, you have to try to make it accord
    with the process stack limit.  */
-size_t re_max_failures = 40000;
+size_t emacs_re_max_failures = 40000;
 # else
-size_t re_max_failures = 4000;
+size_t emacs_re_max_failures = 4000;
 # endif
 
 union fail_stack_elt
@@ -1304,7 +1317,7 @@ WEAK_ALIAS (__re_set_syntax, re_set_syntax)
 
 
 /* Double the size of FAIL_STACK, up to a limit
-   which allows approximately `re_max_failures' items.
+   which allows approximately `emacs_re_max_failures' items.
 
    Return 1 if succeeds, and 0 if either ran out of memory
    allocating space for it or it was already too large.
@@ -1319,19 +1332,19 @@ WEAK_ALIAS (__re_set_syntax, re_set_syntax)
 #define FAIL_STACK_GROWTH_FACTOR 4
 
 #define GROW_FAIL_STACK(fail_stack)					\
-  (((fail_stack).size >= re_max_failures * TYPICAL_FAILURE_SIZE)        \
+  (((fail_stack).size >= emacs_re_max_failures * TYPICAL_FAILURE_SIZE)        \
    ? 0									\
    : ((fail_stack).stack						\
       = REGEX_REALLOCATE_STACK ((fail_stack).stack,			\
 	  (fail_stack).size * sizeof (fail_stack_elt_t),		\
-          min (re_max_failures * TYPICAL_FAILURE_SIZE,                  \
+          min (emacs_re_max_failures * TYPICAL_FAILURE_SIZE,                  \
                ((fail_stack).size * FAIL_STACK_GROWTH_FACTOR))          \
           * sizeof (fail_stack_elt_t)),                                 \
 									\
       (fail_stack).stack == NULL					\
       ? 0								\
       : ((fail_stack).size						\
-         = (min (re_max_failures * TYPICAL_FAILURE_SIZE,                \
+         = (min (emacs_re_max_failures * TYPICAL_FAILURE_SIZE,                \
                  ((fail_stack).size * FAIL_STACK_GROWTH_FACTOR))),      \
 	 1)))
 
@@ -3638,9 +3651,9 @@ regex_compile (const_re_char *pattern, size_t size,
   {
     int num_regs = bufp->re_nsub + 1;
 
-    if (fail_stack.size < re_max_failures * TYPICAL_FAILURE_SIZE)
+    if (fail_stack.size < emacs_re_max_failures * TYPICAL_FAILURE_SIZE)
       {
-	fail_stack.size = re_max_failures * TYPICAL_FAILURE_SIZE;
+	fail_stack.size = emacs_re_max_failures * TYPICAL_FAILURE_SIZE;
 	falk_stack.stack = realloc (fail_stack.stack,
 				    fail_stack.size * sizeof *falk_stack.stack);
       }
diff --git a/src/regex.h b/src/regex.h
index 34c9929..1d439de 100644
--- a/src/regex.h
+++ b/src/regex.h
@@ -186,7 +186,12 @@
 #endif
 
 /* Roughly the maximum number of failure points on the stack.  */
-extern size_t re_max_failures;
+extern size_t emacs_re_max_failures;
+
+#ifdef emacs
+/* Amount of memory that we can safely stack allocate.  */
+extern ptrdiff_t emacs_re_safe_alloca;
+#endif
 
 \f
 /* Define combinations of the above bits for the standard possibilities.
-- 
2.9.3


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* bug#24751: 26.0.50; Regex stack overflow not detected properly (gets "Variable binding depth exceeds max-specpdl-size")
  2017-01-02 18:30                           ` npostavs
@ 2017-01-02 19:22                             ` Eli Zaretskii
  2017-01-08 23:49                               ` npostavs
  0 siblings, 1 reply; 22+ messages in thread
From: Eli Zaretskii @ 2017-01-02 19:22 UTC (permalink / raw)
  To: npostavs; +Cc: 24751

> From: npostavs@users.sourceforge.net
> Cc: 24751@debbugs.gnu.org
> Date: Mon, 02 Jan 2017 13:30:26 -0500
> 
> > How about the below?
> 
> Looks good, I've incorporated it into the patch:

Fine with me, thanks.





^ permalink raw reply	[flat|nested] 22+ messages in thread

* bug#24751: 26.0.50; Regex stack overflow not detected properly (gets "Variable binding depth exceeds max-specpdl-size")
  2017-01-02 19:22                             ` Eli Zaretskii
@ 2017-01-08 23:49                               ` npostavs
  0 siblings, 0 replies; 22+ messages in thread
From: npostavs @ 2017-01-08 23:49 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 24751

tags 24751 fixed
close 24751 26.1
quit

I've pushed to master.

1: 2017-01-08 18:45:52 -0500 9a19f26cd796c7321f659a8dbea5296b0eeea51d
  Fix computation of regex stack limit

2: 2017-01-08 18:45:52 -0500 13c6f1d185d301aad2f6d756c148acb2edd0889f
  Use expanded stack during regex matches





^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2017-01-08 23:49 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-10-21  3:54 bug#24751: 26.0.50; Regex stack overflow not detected properly (gets "Variable binding depth exceeds max-specpdl-size") npostavs
2016-11-04  8:22 ` Eli Zaretskii
2016-11-05 19:34   ` npostavs
2016-11-06 15:45     ` Eli Zaretskii
2016-11-13  5:39       ` npostavs
2016-11-13 16:12         ` Eli Zaretskii
2016-11-15  3:08           ` npostavs
2016-11-15 16:12             ` Eli Zaretskii
2016-11-16  1:06               ` npostavs
2016-11-16 16:25                 ` Eli Zaretskii
2016-11-16 23:25                   ` npostavs
2016-11-17 16:21                     ` Eli Zaretskii
2016-11-19 10:02                       ` Eli Zaretskii
2017-01-01 18:33                       ` npostavs
2017-01-01 18:41                         ` Eli Zaretskii
2017-01-01 18:57                           ` npostavs
2017-01-01 20:06                             ` Eli Zaretskii
2017-01-02  4:49                       ` npostavs
2017-01-02 15:24                         ` Eli Zaretskii
2017-01-02 18:30                           ` npostavs
2017-01-02 19:22                             ` Eli Zaretskii
2017-01-08 23:49                               ` npostavs

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).