<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE bugzilla SYSTEM "https://bugs.webkit.org/page.cgi?id=bugzilla.dtd">

<bugzilla version="5.0.4.1"
          urlbase="https://bugs.webkit.org/"
          
          maintainer="admin@webkit.org"
>

    <bug>
          <bug_id>140269</bug_id>
          
          <creation_ts>2015-01-08 15:07:16 -0800</creation_ts>
          <short_desc>Breakpoint doesn&apos;t fire in this HTML5 game</short_desc>
          <delta_ts>2015-01-10 16:49:28 -0800</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>WebKit</product>
          <component>JavaScriptCore</component>
          <version>528+ (Nightly build)</version>
          <rep_platform>All</rep_platform>
          <op_sys>All</op_sys>
          <bug_status>RESOLVED</bug_status>
          <resolution>FIXED</resolution>
          
          
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords>InRadar</keywords>
          <priority>P2</priority>
          <bug_severity>Normal</bug_severity>
          <target_milestone>---</target_milestone>
          
          
          <everconfirmed>1</everconfirmed>
          <reporter name="Michael Saboff">msaboff</reporter>
          <assigned_to name="Michael Saboff">msaboff</assigned_to>
          <cc>ddkilzer</cc>
    
    <cc>joepeck</cc>
    
    <cc>mark.lam</cc>
    
    <cc>timothy</cc>
          

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>1059964</commentid>
    <comment_count>0</comment_count>
    <who name="Michael Saboff">msaboff</who>
    <bug_when>2015-01-08 15:07:16 -0800</bug_when>
    <thetext>* SUMMARY
No JS breakpoints hit in this HTML5 game

* STEPS TO REPRODUCE
1. Go to http://goldenminer.org/#
2. Set a breakpoint on g.js line 268, the first line after &quot;doMine: function() {&quot;

* RESULTS
Breakpoint was not hit.

rdar://problem/15113345</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1059987</commentid>
    <comment_count>1</comment_count>
      <attachid>244305</attachid>
    <who name="Michael Saboff">msaboff</who>
    <bug_when>2015-01-08 15:46:13 -0800</bug_when>
    <thetext>Created attachment 244305
Patch</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1059996</commentid>
    <comment_count>2</comment_count>
      <attachid>244305</attachid>
    <who name="Joseph Pecoraro">joepeck</who>
    <bug_when>2015-01-08 16:00:21 -0800</bug_when>
    <thetext>Comment on attachment 244305
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=244305&amp;action=review

Test looks good to me with nits. I don&apos;t think I&apos;m qualified to review the parser change.

&gt; LayoutTests/inspector/debugger/breakpoint-columns.html:41
&gt; +        // Create the breakpoint and its actions before sending anything to the backend.

Nit: Unnecessary and incorrect comment (no actions).

&gt; LayoutTests/inspector/debugger/breakpoint-columns.html:43
&gt; +        breakpoint.autoContinue = false;

Nit: This is the default value, you should not need to set it, this shouldn&apos;t be doing anything.

&gt; LayoutTests/inspector/debugger/breakpoint-columns.html:53
&gt; +    WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.CallFramesDidChange,
&gt; +function(event) {

Style: You should put the &quot;function(event) {&quot; on the previous line.

&gt; LayoutTests/inspector/debugger/breakpoint-columns.html:58
&gt; +        if (WebInspector.debuggerManager.activeCallFrame) {
&gt; +            var stopLocation = &quot;line: &quot; +
&gt; +                WebInspector.debuggerManager.activeCallFrame.sourceCodeLocation.lineNumber +
&gt; +                &quot;, column: &quot; +
&gt; +                WebInspector.debuggerManager.activeCallFrame.sourceCodeLocation.columnNumber;

This would read much better storing activeCallFrame into a local. Also, I think this test will now work if you just early return if there is no call frame.

    var activeCallFrame = WebInspector.debuggerManager.activeCallFrame;
    if (!activeCallFrame)
        return;

    var stopLocation = &quot;line: &quot; + activeCallFrame.sourceCodeLocation.lineNumber + &quot;m column: &quot; activeCallFrame.sourceCodeLocation.columnNumber;
    ...
    WebInspector.debuggerManager.resume();

&gt; LayoutTests/inspector/debugger/breakpoint-columns.html:61
&gt; +            InspectorTest.evaluateInPage(&quot;console.log(&apos;Paused at &quot; + stopLocation + &quot;&apos;)&quot;)

Style: Since you use semicolon&apos;s elsewhere, you may want a semicolon at the end of this statement.

&gt; LayoutTests/inspector/debugger/breakpoint-columns.html:68
&gt; +    WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.Resumed,
&gt; +function(event) {

Style: You should put the &quot;function(event) {&quot; on the previous line.

&gt; LayoutTests/inspector/debugger/breakpoint-columns.html:93
&gt; +    &lt;p&gt;Testing that breakpoints can be set at various line / column combinations&apos;.&lt;/p&gt;

Unexpected single quote.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1060004</commentid>
    <comment_count>3</comment_count>
      <attachid>244309</attachid>
    <who name="Michael Saboff">msaboff</who>
    <bug_when>2015-01-08 16:12:23 -0800</bug_when>
    <thetext>Created attachment 244309
Patch with reviewer&apos;s suggested changes.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1060015</commentid>
    <comment_count>4</comment_count>
      <attachid>244309</attachid>
    <who name="Geoffrey Garen">ggaren</who>
    <bug_when>2015-01-08 16:45:29 -0800</bug_when>
    <thetext>Comment on attachment 244309
Patch with reviewer&apos;s suggested changes.

View in context: https://bugs.webkit.org/attachment.cgi?id=244309&amp;action=review

&gt; Source/JavaScriptCore/ChangeLog:8
&gt; +        When parsing a single line cached function, use the lineStartOffset of the

Why does this only matter in the single line function case?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1060020</commentid>
    <comment_count>5</comment_count>
      <attachid>244309</attachid>
    <who name="Mark Lam">mark.lam</who>
    <bug_when>2015-01-08 17:00:01 -0800</bug_when>
    <thetext>Comment on attachment 244309
Patch with reviewer&apos;s suggested changes.

r=me.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1060022</commentid>
    <comment_count>6</comment_count>
    <who name="Michael Saboff">msaboff</who>
    <bug_when>2015-01-08 17:09:43 -0800</bug_when>
    <thetext>(In reply to comment #4)
&gt; Comment on attachment 244309 [details]
&gt; Patch with reviewer&apos;s suggested changes.
&gt; 
&gt; View in context:
&gt; https://bugs.webkit.org/attachment.cgi?id=244309&amp;action=review
&gt; 
&gt; &gt; Source/JavaScriptCore/ChangeLog:8
&gt; &gt; +        When parsing a single line cached function, use the lineStartOffset of the
&gt; 
&gt; Why does this only matter in the single line function case?

The lineStartOffset is used to compute the column.  It appears that lineStartOffset has two different meanings.

For multiline functions, it is the offset in the source string for the current line.  

For single line functions, it is the offset of the &quot;{&quot; of the next outer most enclosing function.  That is the case that we are fixing here.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1060101</commentid>
    <comment_count>7</comment_count>
    <who name="Mark Lam">mark.lam</who>
    <bug_when>2015-01-09 02:01:37 -0800</bug_when>
    <thetext>(In reply to comment #6)
&gt; (In reply to comment #4)
&gt; &gt; &gt; Source/JavaScriptCore/ChangeLog:8
&gt; &gt; &gt; +        When parsing a single line cached function, use the lineStartOffset of the
&gt; &gt; 
&gt; &gt; Why does this only matter in the single line function case?
&gt; 
&gt; The lineStartOffset is used to compute the column.  It appears that
&gt; lineStartOffset has two different meanings.
&gt; 
&gt; For multiline functions, it is the offset in the source string for the
&gt; current line.  
&gt; 
&gt; For single line functions, it is the offset of the &quot;{&quot; of the next outer
&gt; most enclosing function.  That is the case that we are fixing here.

No, this explanation is incorrect.  There is only 1 meaning to lineStartOffset.  After thinking thru this some more, I think the solution may be wrong too.  Details below:

The Single Line case
====================
Test source code:
function columnTest1(){var x=function x(){setInterval(function y(){})};(function z(){console.log(&quot;column test 1&quot;)})()}

The parser passes (in Parser::parseFunctionInfo()) for this code goes as follows as the code gets executed:

Pass 1: Parsing the global program
  SourceCode starts at startChar 0 (base 0), line 1 (base 1), column 1 (base 1).

  1. Scan over function columnTest1:
     - Function is NOT found in parser cache. 
     - Body start OpenParen is at location (line = 1, lineStartOffset = 0, startOffset = 22, endOffset = 23).
     *** Note: the lineStartOffset is at 0 because the SourceCode startChar is 0. ***

  2. Scan over function x:
     - Function is NOT found in parser cache. 
     - Body start OpenParen is at location (line = 1, lineStartOffset = 0, startOffset = 41, endOffset = 42).
     - Function body is added to the parser cache.
     *** Note: the end of the function (not shown here) should have lineStartOffset of 0 (based on SourceCode
               startChar) because the whole function is on 1 line. ***

  3. Scan over function y: This function is not relevant to this discussion.

  4. Scan over function z:
     - Function is NOT found in parser cache. 
     - Body start OpenParen is at location (line = 1, lineStartOffset = 0, startOffset = 84, endOffset = 85).
     - Function body is added to the parser cache.

Pass 2: Parsing columnTest1.
  SourceCode starts at startChar 22 (base 0), line 1 (base 1), column 23 (base 1). 
  *** Note: the startChar is 22 because that’s where the body of columnTest1 starts (see above).

  5. Scan over function x:
     - Function is FOUND in parser cache, and will be parsed for compilation from the cached source string. 
     - Actual Body start OpenParen is at location (line = 1, lineStartOffset = 22, startOffset = 41, endOffset = 42).
     *** Note: the actual lineStartOffset of this function is 22 because it’s SourceCode startChar is 22, not 0.
               However, we’ll be parsing the cached source string which has a lineStartOffset of 0.

               Similarly, we would expect the actual lineStartOffset of the CloseParen to be 22.
               But because we’re actually parsing the cached source string, the lexer token info at the end
               will have a lineStartOffset of 0.

     After scanning over function x based on the cached string, we need to update the lexer to point to last token
     so that we can continue parsing:

         m_lexer-&gt;setOffset(m_token.m_location.endOffset, m_token.m_location.lineStartOffset);

     Unfortunately, that lineStartOffset of that last token is from the cached source string (i.e. 0) when we expect
     it to be for the current source string (i.e. 22).  This is the bug that is being fixed by setting the token
     lineStartOffset to the starting lineStartOffset before we setOffset() on the lexer.

     But why don’t we do this when the source code is multi-line?  Well, see below ...


The Multi-Line case
===================
Test source code:
// ...
// ...
function columnTest1() { // line 3
    var x=function x() { // line 4
        setInterval(function y(){}) // line 5
    }; // end of function at line 6, column 5
    (function z() { // line 7
        console.log(&quot;column test 1&quot;)
    })()
} // line 10

function columnTest2() { // line 12
    var r, s, t, u, v, w, x=function x() { // line 13
        setInterval(function y(){}) // line 14
    }; // end of function at line 15, column 5
}

The parser passes (in Parser::parseFunctionInfo()) for this code goes as follows as the code gets executed:

Pass 1: Parsing the global program
  SourceCode starts at startChar 0 (base 0), line 1 (base 1), column 1 (base 1).

  1. Scan over function columnTest1:
     - Body start OpenParen is at location (line = 3, lineStartOffset = 123, startOffset = 146, endOffset = 147).
     *** Note: the lineStartOffset doesn’t start at 0 because it is on a different line from the start of the source (line 3).

  2. Scan over function x:
     - Body start OpenParen is at location (line = 4, lineStartOffset = 148, startOffset = 171, endOffset = 1712).
     *** Note: the lineStartOffset also doesn’t start at 0 because it is on a different line from the start of the source (line 4).
               Similarly, we would expect the lineStartOffset of the end of the function (line 6) to not be 0 as well.

  3. Scan over function y: This function is not relevant to this discussion.

  4. Scan over function z:
     - Body start OpenParen is at location (line = 7, lineStartOffset = 216, startOffset = 234, endOffset = 235).

Pass 2: Parsing columnTest1.
  SourceCode starts at startChar 146 (base 0), line 3 (base 1), column 24 (base 1). 
  *** Note: the startChar is 146 because that’s where the body of columnTest1 starts on line 3.

  5. Scan over function x:
     - Function is FOUND in parser cache, and will be parsed for compilation from the cached source string. 
     - Actual Body start OpenParen is at location (line = 4, lineStartOffset = 148, startOffset = 171, endOffset = 172).

     *** Note: the lineStartOffset of the end of the function does not depend on the first line of the function
               because, by definition, they are on different lines.

               But does this mean we don’t have to adjust the lineStartOffset here?  No, see below ...

Consider columnTest2 which also has a function x which has a body that is identical to the one in columnTest1.  However, because this function x body is located at a different place in the source string, it follows that the body end lineStartOffset must necessarily be different than that of the one in the parser cache (which is based on the columnTest1 function x).  It should be fixed up based on where its body start lineStartOffset is.

Hence, the proper fix should instead be:

        unsigned currentLineStartOffset = m_token.m_location.lineStartOffset;

        ...

        if (endColumnIsOnStartLine)
            m_token.m_location.lineStartOffset = currentLineStartOffset;
        else
            m_token.m_location.lineStartOffset += (currentLineStartOffset - cachedInfo-&gt;openBraceLineStartOffset);

Note: cachedInfo is of type SourceProviderCacheItem* here, and SourceProviderCacheItem::openBraceLineStartOffset does not currently exist.  We’ll need to add it where the cachedInfo is initialized.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1060102</commentid>
    <comment_count>8</comment_count>
      <attachid>244309</attachid>
    <who name="Mark Lam">mark.lam</who>
    <bug_when>2015-01-09 02:03:12 -0800</bug_when>
    <thetext>Comment on attachment 244309
Patch with reviewer&apos;s suggested changes.

In light of the data I’ve just provided, we know that this patch is incorrect.  Hence, I’m reversing my r+.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1060130</commentid>
    <comment_count>9</comment_count>
    <who name="Mark Lam">mark.lam</who>
    <bug_when>2015-01-09 07:51:38 -0800</bug_when>
    <thetext>(In reply to comment #7)
...
&gt; The Multi-Line case
&gt; ===================
&gt; Test source code:
&gt; // ...
&gt; // ...
&gt; function columnTest1() { // line 3
&gt;     var x=function x() { // line 4
&gt;         setInterval(function y(){}) // line 5
&gt;     }; // end of function at line 6, column 5
&gt;     (function z() { // line 7
&gt;         console.log(&quot;column test 1&quot;)
&gt;     })()
&gt; } // line 10
&gt; 
&gt; function columnTest2() { // line 12
&gt;     var r, s, t, u, v, w, x=function x() { // line 13
&gt;         setInterval(function y(){}) // line 14
&gt;     }; // end of function at line 15, column 5
&gt; }
...
&gt; Consider columnTest2 which also has a function x which has a body that is
&gt; identical to the one in columnTest1.

Some corrections:
1. I added the line number comments in order to help us understand the differences.  In order for the test to work, we cannot have the line number comments there because they will make the 2 x functions different and not use the same cached info.

2. I deliberately have more characters before the start of the columnTest2 x’s “{&quot;.  This difference is ok.  It is the content from the “{&quot; onwards that must be the same up till the “}”. 

3. In comment #7, I also made the error of using the OpenParen location as the start of the function body.  That is not correct.  It is the OpenBrace location that starts the function body.  However, since the 2 always have the same lineStartOffset in these examples, the examples are still correct in terms of the body start lineStartOffset values that we would expect to see.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1060185</commentid>
    <comment_count>10</comment_count>
    <who name="Michael Saboff">msaboff</who>
    <bug_when>2015-01-09 11:05:02 -0800</bug_when>
    <thetext>(In reply to comment #7)
&gt; (In reply to comment #6)
&gt; &gt; (In reply to comment #4)
&gt; &gt; &gt; &gt; Source/JavaScriptCore/ChangeLog:8

&gt; Hence, the proper fix should instead be:
&gt; 
&gt;         unsigned currentLineStartOffset = m_token.m_location.lineStartOffset;
&gt; 
&gt;         ...
&gt; 
&gt;         if (endColumnIsOnStartLine)
&gt;             m_token.m_location.lineStartOffset = currentLineStartOffset;
&gt;         else
&gt;             m_token.m_location.lineStartOffset += (currentLineStartOffset -
&gt; cachedInfo-&gt;openBraceLineStartOffset);
&gt; 
&gt; Note: cachedInfo is of type SourceProviderCacheItem* here, and
&gt; SourceProviderCacheItem::openBraceLineStartOffset does not currently exist. 
&gt; We’ll need to add it where the cachedInfo is initialized.

I implemented the suggested changes.  I got the open paren&apos;s lineStartOffset from the startLocation.  Where the SourceProviderCacheItemCreationParameters struct is created I have, using the newly added field:

      parameters.openBraceLineStartOffset = startLocation.lineStartOffset;

These suggested changes caused a crash in a debug build in the following layout tests
    webgl/1.0.2/conformance/more/glsl/uniformOutOfBounds.html  
    js/regress/nested-function-parsing.html    
    js/slow-stress/nested-function-parsing-random.html 
    compositing/culling/unscrolled-within-boxshadow.html
    compositing/culling/scrolled-within-boxshadow.html

All similar to:
Process:               DumpRenderTree [74439]
Path:                  /Volumes/VOLUME/*/DumpRenderTree
Identifier:            DumpRenderTree
Version:               0
Code Type:             X86-64 (Native)
Parent Process:        Python [52192]
Responsible:           Terminal [379]
User ID:               501

Date/Time:             2015-01-09 10:35:27.575 -0800
OS Version:            Mac OS X 10.11 (15A64)
Report Version:        11
Anonymous UUID:        D41B71B4-1D4F-DCC9-DE79-773C9742C2B3

Sleep/Wake UUID:       A4F62134-B26B-4BC0-85CA-EA39A6BC4AEB

Time Awake Since Boot: 120000 seconds
Time Since Wake:       3800 seconds

Crashed Thread:        0  Dispatch queue: com.apple.main-thread

Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
Exception Codes:       KERN_INVALID_ADDRESS at 0x00000000bbadbeef

VM Regions Near 0xbbadbeef:
--&gt; 
    __TEXT                 0000000104634000-00000001046c9000 [  596K] r-x/rwx SM=COW  /Volumes/VOLUME/*

Application Specific Information:
CRASHING TEST: webgl/1.0.2/conformance/more/glsl/uniformOutOfBounds.html

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   com.apple.JavaScriptCore      	0x00000001052c64e7 WTFCrash + 39
1   com.apple.JavaScriptCore      	0x00000001050552dc JSC::Lexer&lt;unsigned char&gt;::setOffset(int, int) + 188
2   com.apple.JavaScriptCore      	0x000000010516086b bool JSC::Parser&lt;JSC::Lexer&lt;unsigned char&gt; &gt;::parseFunctionInfo&lt;JSC::ASTBuilder&gt;(JSC::ASTBuilder&amp;, JSC::FunctionRequirements, JSC::FunctionParseMode, bool, JSC::Identifier const*&amp;, JSC::ASTBuilder::FormalParameterList&amp;, JSC::ASTBuilder::FunctionBody&amp;, unsigned int&amp;, unsigned int&amp;, int&amp;, unsigned int&amp;) + 4795
3   com.apple.JavaScriptCore      	0x000000010515e466 JSC::ASTBuilder::Expression JSC::Parser&lt;JSC::Lexer&lt;unsigned char&gt; &gt;::parseMemberExpression&lt;JSC::ASTBuilder&gt;(JSC::ASTBuilder&amp;) + 486
4   com.apple.JavaScriptCore      	0x000000010515d35b JSC::ASTBuilder::Expression JSC::Parser&lt;JSC::Lexer&lt;unsigned char&gt; &gt;::parseUnaryExpression&lt;JSC::ASTBuilder&gt;(JSC::ASTBuilder&amp;) + 1051
5   com.apple.JavaScriptCore      	0x000000010515c62a JSC::ASTBuilder::Expression JSC::Parser&lt;JSC::Lexer&lt;unsigned char&gt; &gt;::parseBinaryExpression&lt;JSC::ASTBuilder&gt;(JSC::ASTBuilder&amp;) + 186
6   com.apple.JavaScriptCore      	0x000000010515bc5c JSC::ASTBuilder::Expression JSC::Parser&lt;JSC::Lexer&lt;unsigned char&gt; &gt;::parseConditionalExpression&lt;JSC::ASTBuilder&gt;(JSC::ASTBuilder&amp;) + 60
7   com.apple.JavaScriptCore      	0x000000010515b17e JSC::ASTBuilder::Expression JSC::Parser&lt;JSC::Lexer&lt;unsigned char&gt; &gt;::parseAssignmentExpression&lt;JSC::ASTBuilder&gt;(JSC::ASTBuilder&amp;) + 590
8   com.apple.JavaScriptCore      	0x0000000105162ae4 JSC::ASTBuilder::Arguments JSC::Parser&lt;JSC::Lexer&lt;unsigned char&gt; &gt;::parseArguments&lt;JSC::ASTBuilder&gt;(JSC::ASTBuilder&amp;, JSC::Parser&lt;JSC::Lexer&lt;unsigned char&gt; &gt;::SpreadMode) + 1300
9   com.apple.JavaScriptCore      	0x000000010515ec09 JSC::ASTBuilder::Expression JSC::Parser&lt;JSC::Lexer&lt;unsigned char&gt; &gt;::parseMemberExpression&lt;JSC::ASTBuilder&gt;(JSC::ASTBuilder&amp;) + 2441
10  com.apple.JavaScriptCore      	0x000000010515d35b JSC::ASTBuilder::Expression JSC::Parser&lt;JSC::Lexer&lt;unsigned char&gt; &gt;::parseUnaryExpression&lt;JSC::ASTBuilder&gt;(JSC::ASTBuilder&amp;) + 1051
11  com.apple.JavaScriptCore      	0x000000010515c62a JSC::ASTBuilder::Expression JSC::Parser&lt;JSC::Lexer&lt;unsigned char&gt; &gt;::parseBinaryExpression&lt;JSC::ASTBuilder&gt;(JSC::ASTBuilder&amp;) + 186
12  com.apple.JavaScriptCore      	0x000000010515bc5c JSC::ASTBuilder::Expression JSC::Parser&lt;JSC::Lexer&lt;unsigned char&gt; &gt;::parseConditionalExpression&lt;JSC::ASTBuilder&gt;(JSC::ASTBuilder&amp;) + 60
13  com.apple.JavaScriptCore      	0x000000010515b17e JSC::ASTBuilder::Expression JSC::Parser&lt;JSC::Lexer&lt;unsigned char&gt; &gt;::parseAssignmentExpression&lt;JSC::ASTBuilder&gt;(JSC::ASTBuilder&amp;) + 590
14  com.apple.JavaScriptCore      	0x000000010515a921 JSC::ASTBuilder::Expression JSC::Parser&lt;JSC::Lexer&lt;unsigned char&gt; &gt;::parseExpression&lt;JSC::ASTBuilder&gt;(JSC::ASTBuilder&amp;) + 177
15  com.apple.JavaScriptCore      	0x0000000105159d0a JSC::ASTBuilder::Statement JSC::Parser&lt;JSC::Lexer&lt;unsigned char&gt; &gt;::parseExpressionOrLabelStatement&lt;JSC::ASTBuilder&gt;(JSC::ASTBuilder&amp;) + 138
16  com.apple.JavaScriptCore      	0x0000000105151916 JSC::ASTBuilder::Statement JSC::Parser&lt;JSC::Lexer&lt;unsigned char&gt; &gt;::parseStatement&lt;JSC::ASTBuilder&gt;(JSC::ASTBuilder&amp;, JSC::Identifier const*&amp;, unsigned int*) + 998
17  com.apple.JavaScriptCore      	0x00000001050f9bac JSC::ASTBuilder::SourceElements JSC::Parser&lt;JSC::Lexer&lt;unsigned char&gt; &gt;::parseSourceElements&lt;JSC::ASTBuilder&gt;(JSC::ASTBuilder&amp;, JSC::SourceElementsMode) + 108
18  com.apple.JavaScriptCore      	0x0000000105152297 JSC::ASTBuilder::Statement JSC::Parser&lt;JSC::Lexer&lt;unsigned char&gt; &gt;::parseBlockStatement&lt;JSC::ASTBuilder&gt;(JSC::ASTBuilder&amp;) + 327
19  com.apple.JavaScriptCore      	0x00000001051516c5 JSC::ASTBuilder::Statement JSC::Parser&lt;JSC::Lexer&lt;unsigned char&gt; &gt;::parseStatement&lt;JSC::ASTBuilder&gt;(JSC::ASTBuilder&amp;, JSC::Identifier const*&amp;, unsigned int*) + 405
20  com.apple.JavaScriptCore      	0x00000001050f9bac JSC::ASTBuilder::SourceElements JSC::Parser&lt;JSC::Lexer&lt;unsigned char&gt; &gt;::parseSourceElements&lt;JSC::ASTBuilder&gt;(JSC::ASTBuilder&amp;, JSC::SourceElementsMode) + 108
21  com.apple.JavaScriptCore      	0x00000001050f9588 JSC::Parser&lt;JSC::Lexer&lt;unsigned char&gt; &gt;::parseInner() + 232
22  com.apple.JavaScriptCore      	0x000000010525a7e5 std::__1::unique_ptr&lt;JSC::FunctionNode, std::__1::default_delete&lt;JSC::FunctionNode&gt; &gt; JSC::Parser&lt;JSC::Lexer&lt;unsigned char&gt; &gt;::parse&lt;JSC::FunctionNode&gt;(JSC::ParserError&amp;, bool) + 405
23  com.apple.JavaScriptCore      	0x0000000105259a83 std::__1::unique_ptr&lt;JSC::FunctionNode, std::__1::default_delete&lt;JSC::FunctionNode&gt; &gt; JSC::parse&lt;JSC::FunctionNode&gt;(JSC::VM*, JSC::SourceCode const&amp;, JSC::FunctionParameters*, JSC::Identifier const&amp;, JSC::JSParserStrictness, JSC::JSParserMode, JSC::ParserError&amp;, JSC::JSTextPosition*, bool) + 403
24  com.apple.JavaScriptCore      	0x0000000105253ed5 JSC::generateFunctionCodeBlock(JSC::VM&amp;, JSC::UnlinkedFunctionExecutable*, JSC::SourceCode const&amp;, JSC::CodeSpecializationKind, JSC::DebuggerMode, JSC::ProfilerMode, JSC::UnlinkedFunctionKind, bool, JSC::ParserError&amp;) + 325
25  com.apple.JavaScriptCore      	0x0000000105253c16 JSC::UnlinkedFunctionExecutable::codeBlockFor(JSC::VM&amp;, JSC::SourceCode const&amp;, JSC::CodeSpecializationKind, JSC::DebuggerMode, JSC::ProfilerMode, bool, JSC::ParserError&amp;) + 374
26  com.apple.JavaScriptCore      	0x0000000104d71093 JSC::ScriptExecutable::newCodeBlockFor(JSC::CodeSpecializationKind, JSC::JSFunction*, JSC::JSScope**, JSC::JSObject*&amp;) + 1731
27  com.apple.JavaScriptCore      	0x0000000104d717de JSC::ScriptExecutable::prepareForExecutionImpl(JSC::ExecState*, JSC::JSFunction*, JSC::JSScope**, JSC::CodeSpecializationKind) + 110
28  com.apple.JavaScriptCore      	0x00000001049a24f5 JSC::ScriptExecutable::prepareForExecution(JSC::ExecState*, JSC::JSFunction*, JSC::JSScope**, JSC::CodeSpecializationKind) + 101
29  com.apple.JavaScriptCore      	0x0000000105083951 JSC::LLInt::setUpCall(JSC::ExecState*, JSC::Instruction*, JSC::CodeSpecializationKind, JSC::JSValue, JSC::LLIntCallLinkInfo*) + 305
30  com.apple.JavaScriptCore      	0x0000000105083806 JSC::LLInt::genericCall(JSC::ExecState*, JSC::Instruction*, JSC::CodeSpecializationKind) + 230
31  com.apple.JavaScriptCore      	0x000000010508008c llint_slow_path_call + 60
32  com.apple.JavaScriptCore      	0x000000010508cffb llint_entry + 25615
33  ???                           	0x00002f1545e01a3a 0 + 51768413133370
34  com.apple.JavaScriptCore      	0x000000010508d1f7 llint_entry + 26123
35  com.apple.JavaScriptCore      	0x000000010508d00a llint_entry + 25630
36  com.apple.JavaScriptCore      	0x000000010508d00a llint_entry + 25630
37  com.apple.JavaScriptCore      	0x00000001050869a9 vmEntryToJavaScript + 361
38  com.apple.JavaScriptCore      	0x0000000104f13ddc JSC::JITCode::execute(JSC::VM*, JSC::ProtoCallFrame*) + 252
39  com.apple.JavaScriptCore      	0x0000000104ef87ff JSC::Interpreter::executeCall(JSC::ExecState*, JSC::JSObject*, JSC::CallType, JSC::CallData const&amp;, JSC::JSValue, JSC::ArgList const&amp;) + 1487
40  com.apple.JavaScriptCore      	0x0000000104a0a45e JSC::call(JSC::ExecState*, JSC::JSValue, JSC::CallType, JSC::CallData const&amp;, JSC::JSValue, JSC::ArgList const&amp;) + 190
41  com.apple.JavaScriptCore      	0x0000000104a0a4c3 JSC::call(JSC::ExecState*, JSC::JSValue, JSC::CallType, JSC::CallData const&amp;, JSC::JSValue, JSC::ArgList const&amp;, JSC::JSValue*) + 83
42  com.apple.WebCore             	0x0000000109978e8b WebCore::JSMainThreadExecState::call(JSC::ExecState*, JSC::JSValue, JSC::CallType, JSC::CallData const&amp;, JSC::JSValue, JSC::ArgList const&amp;, JSC::JSValue*) + 107 (JSMainThreadExecState.h:56)
43  com.apple.WebCore             	0x0000000109af4bae WebCore::JSEventListener::handleEvent(WebCore::ScriptExecutionContext*, WebCore::Event*) + 1278 (JSEventListener.cpp:127)
44  com.apple.WebCore             	0x00000001092f3c74 WebCore::EventTarget::fireEventListeners(WebCore::Event*, WebCore::EventTargetData*, WTF::Vector&lt;WebCore::RegisteredEventListener, 1ul, WTF::CrashOnOverflow&gt;&amp;) + 1444 (EventTarget.cpp:255)
45  com.apple.WebCore             	0x00000001092f34ae WebCore::EventTarget::fireEventListeners(WebCore::Event*) + 334 (EventTarget.cpp:207)
46  com.apple.WebCore             	0x000000010921bf4b WebCore::DOMWindow::dispatchEvent(WTF::PassRefPtr&lt;WebCore::Event&gt;, WTF::PassRefPtr&lt;WebCore::EventTarget&gt;) + 539 (DOMWindow.cpp:1897)
47  com.apple.WebCore             	0x00000001092238a5 WebCore::DOMWindow::dispatchLoadEvent() + 293 (DOMWindow.cpp:1855)
48  com.apple.WebCore             	0x00000001090feb8d WebCore::Document::dispatchWindowLoadEvent() + 141 (Document.cpp:3789)
49  com.apple.WebCore             	0x00000001090fc0cd WebCore::Document::implicitClose() + 557 (Document.cpp:2432)
50  com.apple.WebCore             	0x000000010945283b WebCore::FrameLoader::checkCallImplicitClose() + 155 (FrameLoader.cpp:910)
51  com.apple.WebCore             	0x000000010945250e WebCore::FrameLoader::checkCompleted() + 270 (FrameLoader.cpp:857)
52  com.apple.WebCore             	0x0000000109451012 WebCore::FrameLoader::finishedParsing() + 178 (FrameLoader.cpp:777)
53  com.apple.WebCore             	0x00000001091087e3 WebCore::Document::finishedParsing() + 483 (Document.cpp:4605)
54  com.apple.WebCore             	0x00000001095a29f8 WebCore::HTMLConstructionSite::finishedParsing() + 24 (HTMLConstructionSite.cpp:405)
55  com.apple.WebCore             	0x00000001096d7f3a WebCore::HTMLTreeBuilder::finished() + 186 (HTMLTreeBuilder.cpp:2943)
56  com.apple.WebCore             	0x00000001095d0b9e WebCore::HTMLDocumentParser::end() + 190 (HTMLDocumentParser.cpp:426)
57  com.apple.WebCore             	0x00000001095cef5e WebCore::HTMLDocumentParser::attemptToRunDeferredScriptsAndEnd() + 254 (HTMLDocumentParser.cpp:435)
58  com.apple.WebCore             	0x00000001095cecfe WebCore::HTMLDocumentParser::prepareToStopParsing() + 270 (HTMLDocumentParser.cpp:154)
59  com.apple.WebCore             	0x00000001095d0bef WebCore::HTMLDocumentParser::attemptToEnd() + 63 (HTMLDocumentParser.cpp:447)
60  com.apple.WebCore             	0x00000001095d0c48 WebCore::HTMLDocumentParser::finish() + 72 (HTMLDocumentParser.cpp:475)
61  com.apple.WebCore             	0x0000000109189b3c WebCore::DocumentWriter::end() + 332 (DocumentWriter.cpp:247)
62  com.apple.WebCore             	0x0000000109152036 WebCore::DocumentLoader::finishedLoading(double) + 1574 (DocumentLoader.cpp:441)
63  com.apple.WebCore             	0x000000010915197e WebCore::DocumentLoader::notifyFinished(WebCore::CachedResource*) + 270 (DocumentLoader.cpp:375)
64  com.apple.WebCore             	0x0000000108db2952 WebCore::CachedResource::checkNotify() + 130 (CachedResource.cpp:293)
65  com.apple.WebCore             	0x0000000108db2a61 WebCore::CachedResource::finishLoading(WebCore::SharedBuffer*) + 49 (CachedResource.cpp:311)
66  com.apple.WebCore             	0x0000000108dae53a WebCore::CachedRawResource::finishLoading(WebCore::SharedBuffer*) + 218 (CachedRawResource.cpp:105)
67  com.apple.WebCore             	0x000000010a85b0d5 WebCore::SubresourceLoader::didFinishLoading(double) + 581 (SubresourceLoader.cpp:357)
68  com.apple.WebCore             	0x000000010a56fcc5 WebCore::ResourceLoader::didFinishLoading(WebCore::ResourceHandle*, double) + 53 (ResourceLoader.cpp:507)
69  com.apple.WebCore             	0x000000010aafabea -[WebCoreResourceHandleAsDelegate connectionDidFinishLoading:] + 186 (WebCoreResourceHandleAsDelegate.mm:261)
70  com.apple.CFNetwork           	0x00007fff90ba059d __65-[NSURLConnectionInternal _withConnectionAndDelegate:onlyActive:]_block_invoke + 69
71  com.apple.CFNetwork           	0x00007fff90ba0401 -[NSURLConnectionInternal _withConnectionAndDelegate:onlyActive:] + 232
72  com.apple.CFNetwork           	0x00007fff90ba0307 -[NSURLConnectionInternal _withActiveConnectionAndDelegate:] + 48
73  com.apple.CFNetwork           	0x00007fff90ba1314 ___ZN27URLConnectionClient_Classic26_delegate_didFinishLoadingEU13block_pointerFvvE_block_invoke + 104
74  com.apple.CFNetwork           	0x00007fff90c6442d ___ZN27URLConnectionClient_Classic18_withDelegateAsyncEPKcU13block_pointerFvP16_CFURLConnectionPK33CFURLConnectionClientCurrent_VMaxE_block_invoke_2 + 94
75  libdispatch.dylib             	0x00007fff93700958 _dispatch_block_invoke + 457
76  com.apple.CFNetwork           	0x00007fff90afd620 RunloopBlockContext::_invoke_block(void const*, void*) + 24
77  com.apple.CoreFoundation      	0x00007fff8a462734 CFArrayApplyFunction + 68
78  com.apple.CFNetwork           	0x00007fff90afd513 RunloopBlockContext::perform() + 133
79  com.apple.CFNetwork           	0x00007fff90afd2f8 MultiplexerSource::perform() + 282
80  com.apple.CFNetwork           	0x00007fff90afd11a MultiplexerSource::_perform(void*) + 72
81  com.apple.CoreFoundation      	0x00007fff8a496371 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
82  com.apple.CoreFoundation      	0x00007fff8a4888fd __CFRunLoopDoSources0 + 269
83  com.apple.CoreFoundation      	0x00007fff8a487f1f __CFRunLoopRun + 927
84  com.apple.CoreFoundation      	0x00007fff8a487918 CFRunLoopRunSpecific + 296
85  DumpRenderTree                	0x0000000104651124 runTest(std::__1::basic_string&lt;char, std::__1::char_traits&lt;char&gt;, std::__1::allocator&lt;char&gt; &gt; const&amp;) + 5396
86  DumpRenderTree                	0x000000010464fbaa runTestingServerLoop() + 330
87  DumpRenderTree                	0x000000010464f360 dumpRenderTree(int, char const**) + 448
88  DumpRenderTree                	0x00000001046519e6 DumpRenderTreeMain(int, char const**) + 102
89  DumpRenderTree                	0x00000001046a17a2 main + 34
90  libdyld.dylib                 	0x00007fff908d95c9 start + 1</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1060329</commentid>
    <comment_count>11</comment_count>
    <who name="Mark Lam">mark.lam</who>
    <bug_when>2015-01-09 16:23:51 -0800</bug_when>
    <thetext>(In reply to comment #7)
&gt; (In reply to comment #6)
&gt; &gt; (In reply to comment #4)
&gt; &gt; &gt; &gt; Source/JavaScriptCore/ChangeLog:8
&gt; &gt; &gt; &gt; +        When parsing a single line cached function, use the lineStartOffset of the
&gt; &gt; &gt; 
&gt; &gt; &gt; Why does this only matter in the single line function case?
&gt; &gt; 
&gt; &gt; The lineStartOffset is used to compute the column.  It appears that
&gt; &gt; lineStartOffset has two different meanings.
&gt; &gt; 
&gt; &gt; For multiline functions, it is the offset in the source string for the
&gt; &gt; current line.  
&gt; &gt; 
&gt; &gt; For single line functions, it is the offset of the &quot;{&quot; of the next outer
&gt; &gt; most enclosing function.  That is the case that we are fixing here.
&gt; 
&gt; No, this explanation is incorrect.  There is only 1 meaning to
&gt; lineStartOffset.  

Sorry, my tone came off harsher than I intended there.  But it is not true that there are 2 different meanings to the lineStartOffset.  The definition of the lineStartOffset is the offset / character position in the SourceCode string for the start of the current line a.k.a column 0 of the current line.  Michael&apos;s &quot;multiline function&quot; definition is correct.  For the single line function case which you observed, the only reason that it is the offset of the &quot;{&quot; is because that &quot;{&quot; is at start (column 0) of the current one and only line in the source code was being inspected.

&gt; After thinking thru this some more, I think the solution
&gt; may be wrong too.

I was wrong on this part.  Michael&apos;s fix is correct.  I had confused about the parser&apos;s functionCache with the CodeCache&apos;s CodeCacheMap used for reusing UnlinkedCodeBlocks.  With the parser&apos;s functionCache, the scenario of multiple functions reusing the same SourceProviderCacheItem does not exist.  Sorry for the noise.

For the ChangeLog comment, given Geoff&apos;s inquiry, I think perhaps it needs more details on why there is a difference between the single line and multi line scenarios.  How about something like this?

&quot;Consider the following single line program:
function outer(){ function inner1() { doStuff(); }; (function inner2() { doMoreStuff()l })()}

The first time we parse the program, the SourceCode start character is at the start of the program.  On this parser pass, we will cache functions inner1() and inner2() with a lineStartOffset that is at the start of the program.

Subsequently, when we parse function outer(), the SourceCode start character is at the start of outer()&apos;s open brace.  While parsing the body of outer(), we encounter inner1() and will attempt to skip over it by getting its closeBrace position from the parser&apos;s function cache.  Unfortunately, the cached closeBrace position will have a lineStartOffset at the start of the program instead of the start of SourceCode start character where the open brace is.  Hence, if the cached function is a single line function, we need to set its close brace lineStartOffset to that of its open brace.

We don&apos;t need to do this for multi line cached functions because the close brace is guaranteed to be on a different line than the open brace.  Hence, its lineStartOffset will not change with the change of the SourceCode start character.&quot;

Would that work?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1060331</commentid>
    <comment_count>12</comment_count>
      <attachid>244309</attachid>
    <who name="Mark Lam">mark.lam</who>
    <bug_when>2015-01-09 16:24:59 -0800</bug_when>
    <thetext>Comment on attachment 244309
Patch with reviewer&apos;s suggested changes.

r=me with ChangeLog revised.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1060333</commentid>
    <comment_count>13</comment_count>
    <who name="Michael Saboff">msaboff</who>
    <bug_when>2015-01-09 16:30:28 -0800</bug_when>
    <thetext>(In reply to comment #11)
&gt; (In reply to comment #7)
&gt; &gt; (In reply to comment #6)
&gt; &gt; &gt; (In reply to comment #4)
&gt; &gt; &gt; &gt; &gt; Source/JavaScriptCore/ChangeLog:8
&gt; &gt; &gt; &gt; &gt; +        When parsing a single line cached function, use the lineStartOffset of the
&gt; &gt; &gt; &gt; 
&gt; &gt; &gt; &gt; Why does this only matter in the single line function case?
&gt; &gt; &gt; 
&gt; &gt; &gt; The lineStartOffset is used to compute the column.  It appears that
&gt; &gt; &gt; lineStartOffset has two different meanings.
&gt; &gt; &gt; 
&gt; &gt; &gt; For multiline functions, it is the offset in the source string for the
&gt; &gt; &gt; current line.  
&gt; &gt; &gt; 
&gt; &gt; &gt; For single line functions, it is the offset of the &quot;{&quot; of the next outer
&gt; &gt; &gt; most enclosing function.  That is the case that we are fixing here.
&gt; &gt; 
&gt; &gt; No, this explanation is incorrect.  There is only 1 meaning to
&gt; &gt; lineStartOffset.  
&gt; 
&gt; Sorry, my tone came off harsher than I intended there.  But it is not true
&gt; that there are 2 different meanings to the lineStartOffset.  The definition
&gt; of the lineStartOffset is the offset / character position in the SourceCode
&gt; string for the start of the current line a.k.a column 0 of the current line.
&gt; Michael&apos;s &quot;multiline function&quot; definition is correct.  For the single line
&gt; function case which you observed, the only reason that it is the offset of
&gt; the &quot;{&quot; is because that &quot;{&quot; is at start (column 0) of the current one and
&gt; only line in the source code was being inspected.
&gt; 
&gt; &gt; After thinking thru this some more, I think the solution
&gt; &gt; may be wrong too.
&gt; 
&gt; I was wrong on this part.  Michael&apos;s fix is correct.  I had confused about
&gt; the parser&apos;s functionCache with the CodeCache&apos;s CodeCacheMap used for
&gt; reusing UnlinkedCodeBlocks.  With the parser&apos;s functionCache, the scenario
&gt; of multiple functions reusing the same SourceProviderCacheItem does not
&gt; exist.  Sorry for the noise.
&gt; 
&gt; For the ChangeLog comment, given Geoff&apos;s inquiry, I think perhaps it needs
&gt; more details on why there is a difference between the single line and multi
&gt; line scenarios.  How about something like this?
&gt; 
&gt; &quot;Consider the following single line program:
&gt; function outer(){ function inner1() { doStuff(); }; (function inner2() {
&gt; doMoreStuff()l })()}
&gt; 
&gt; The first time we parse the program, the SourceCode start character is at
&gt; the start of the program.  On this parser pass, we will cache functions
&gt; inner1() and inner2() with a lineStartOffset that is at the start of the
&gt; program.
&gt; 
&gt; Subsequently, when we parse function outer(), the SourceCode start character
&gt; is at the start of outer()&apos;s open brace.  While parsing the body of outer(),
&gt; we encounter inner1() and will attempt to skip over it by getting its
&gt; closeBrace position from the parser&apos;s function cache.  Unfortunately, the
&gt; cached closeBrace position will have a lineStartOffset at the start of the
&gt; program instead of the start of SourceCode start character where the open
&gt; brace is.  Hence, if the cached function is a single line function, we need
&gt; to set its close brace lineStartOffset to that of its open brace.
&gt; 
&gt; We don&apos;t need to do this for multi line cached functions because the close
&gt; brace is guaranteed to be on a different line than the open brace.  Hence,
&gt; its lineStartOffset will not change with the change of the SourceCode start
&gt; character.&quot;
&gt; 
&gt; Would that work?

I&apos;ll add this or something similar to the change log.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1060370</commentid>
    <comment_count>14</comment_count>
    <who name="Michael Saboff">msaboff</who>
    <bug_when>2015-01-09 18:44:54 -0800</bug_when>
    <thetext>Committed r178232: &lt;http://trac.webkit.org/changeset/178232&gt;</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1060445</commentid>
    <comment_count>15</comment_count>
    <who name="David Kilzer (:ddkilzer)">ddkilzer</who>
    <bug_when>2015-01-10 15:14:08 -0800</bug_when>
    <thetext>&gt; For a multi-line function, the close brace is guaranteed to be on a different line
&gt; than the open brace. Hence, its lineStartOffset will not change with the change of
&gt; the SourceCode start character

So this isn&apos;t valid JavaScript?

function f()
{ return 1; }</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1060454</commentid>
    <comment_count>16</comment_count>
    <who name="Michael Saboff">msaboff</who>
    <bug_when>2015-01-10 16:49:28 -0800</bug_when>
    <thetext>(In reply to comment #15)
&gt; &gt; For a multi-line function, the close brace is guaranteed to be on a different line
&gt; &gt; than the open brace. Hence, its lineStartOffset will not change with the change of
&gt; &gt; the SourceCode start character
&gt; 
&gt; So this isn&apos;t valid JavaScript?
&gt; 
&gt; function f()
&gt; { return 1; }

Of course it is.  The case being handled here is a function declared inside another function.  The relevant braces are those of the outer function.

Example

function foo()
{ // &lt;-- This opening brace
    function f()
    { return 1; }

    return f;
} // &lt;-- This closing brace</thetext>
  </long_desc>
      
          <attachment
              isobsolete="1"
              ispatch="1"
              isprivate="0"
          >
            <attachid>244305</attachid>
            <date>2015-01-08 15:46:13 -0800</date>
            <delta_ts>2015-01-08 16:12:23 -0800</delta_ts>
            <desc>Patch</desc>
            <filename>140269.patch</filename>
            <type>text/plain</type>
            <size>10697</size>
            <attacher name="Michael Saboff">msaboff</attacher>
            
              <data encoding="base64">SW5kZXg6IFNvdXJjZS9KYXZhU2NyaXB0Q29yZS9DaGFuZ2VMb2cKPT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0gU291
cmNlL0phdmFTY3JpcHRDb3JlL0NoYW5nZUxvZwkocmV2aXNpb24gMTc4MTM1KQorKysgU291cmNl
L0phdmFTY3JpcHRDb3JlL0NoYW5nZUxvZwkod29ya2luZyBjb3B5KQpAQCAtMSwzICsxLDE4IEBA
CisyMDE1LTAxLTA4ICBNaWNoYWVsIFNhYm9mZiAgPG1zYWJvZmZAYXBwbGUuY29tPgorCisgICAg
ICAgIEJyZWFrcG9pbnQgZG9lc24ndCBmaXJlIGluIHRoaXMgSFRNTDUgZ2FtZQorICAgICAgICBo
dHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTQwMjY5CisKKyAgICAgICAg
UmV2aWV3ZWQgYnkgTk9CT0RZIChPT1BTISkuCisKKyAgICAgICAgV2hlbiBwYXJzaW5nIGEgc2lu
Z2xlIGxpbmUgY2FjaGVkIGZ1bmN0aW9uLCB1c2UgdGhlIGxpbmVTdGFydE9mZnNldCBvZiB0aGUK
KyAgICAgICAgbG9jYXRpb24gd2hlcmUgd2UgZm91bmQgdGhlIGNhY2hlZCBmdW5jdGlvbiBpbnN0
ZWFkIG9mIHRoZSBjYWNoZWQgbGluZVN0YXJ0T2Zmc2V0LgorICAgICAgICBUaGUgY2FjaGUgbG9j
YXRpb24ncyBsaW5lU3RhcnRPZmZzZXQgaGFzIG5vdCBiZWVuIGFkanVzdGVkIGZvciBhbnkgcG9z
c2libGUKKyAgICAgICAgY29udGFpbmluZyBmdW5jdGlvbnMuCisKKyAgICAgICAgKiBwYXJzZXIv
UGFyc2VyLmNwcDoKKyAgICAgICAgKEpTQzo6UGFyc2VyPExleGVyVHlwZT46OnBhcnNlRnVuY3Rp
b25JbmZvKToKKwogMjAxNS0wMS0wOCAgSm9zZXBoIFBlY29yYXJvICA8cGVjb3Jhcm9AYXBwbGUu
Y29tPgogCiAgICAgICAgIFdlYiBJbnNwZWN0b3I6IFR5cGUgY2hlY2sgTlNBcnJheSdzIGluIE9i
akMgSW50ZXJmYWNlcyBoYXZlIHRoZSByaWdodCBvYmplY3QgdHlwZXMKSW5kZXg6IFNvdXJjZS9K
YXZhU2NyaXB0Q29yZS9wYXJzZXIvUGFyc2VyLmNwcAo9PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLSBTb3VyY2UvSmF2
YVNjcmlwdENvcmUvcGFyc2VyL1BhcnNlci5jcHAJKHJldmlzaW9uIDE3ODEyMSkKKysrIFNvdXJj
ZS9KYXZhU2NyaXB0Q29yZS9wYXJzZXIvUGFyc2VyLmNwcAkod29ya2luZyBjb3B5KQpAQCAtMTMy
NCw2ICsxMzI0LDcgQEAgdGVtcGxhdGUgPGNsYXNzIFRyZWVCdWlsZGVyPiBib29sIFBhcnNlcgog
ICAgICAgICB1bnNpZ25lZCBib2R5RW5kQ29sdW1uID0gZW5kQ29sdW1uSXNPblN0YXJ0TGluZSA/
CiAgICAgICAgICAgICBlbmRMb2NhdGlvbi5zdGFydE9mZnNldCAtIG1fdG9rZW4ubV9kYXRhLmxp
bmVTdGFydE9mZnNldCA6CiAgICAgICAgICAgICBlbmRMb2NhdGlvbi5zdGFydE9mZnNldCAtIGVu
ZExvY2F0aW9uLmxpbmVTdGFydE9mZnNldDsKKyAgICAgICAgdW5zaWduZWQgY3VycmVudExpbmVT
dGFydE9mZnNldCA9IG1fdG9rZW4ubV9sb2NhdGlvbi5saW5lU3RhcnRPZmZzZXQ7CiAKICAgICAg
ICAgYm9keSA9IGNvbnRleHQuY3JlYXRlRnVuY3Rpb25Cb2R5KHN0YXJ0TG9jYXRpb24sIGVuZExv
Y2F0aW9uLCBib2R5U3RhcnRDb2x1bW4sIGJvZHlFbmRDb2x1bW4sIGNhY2hlZEluZm8tPnN0cmlj
dE1vZGUpOwogICAgICAgICAKQEAgLTEzMzQsNiArMTMzNSwxMCBAQCB0ZW1wbGF0ZSA8Y2xhc3Mg
VHJlZUJ1aWxkZXI+IGJvb2wgUGFyc2VyCiAKICAgICAgICAgY29udGV4dC5zZXRGdW5jdGlvbk5h
bWVTdGFydChib2R5LCBmdW5jdGlvbk5hbWVTdGFydCk7CiAgICAgICAgIG1fdG9rZW4gPSBjYWNo
ZWRJbmZvLT5jbG9zZUJyYWNlVG9rZW4oKTsKKyAgICAgICAgaWYgKGVuZENvbHVtbklzT25TdGFy
dExpbmUpIHsKKyAgICAgICAgICAgIG1fdG9rZW4ubV9sb2NhdGlvbi5saW5lU3RhcnRPZmZzZXQg
PSBjdXJyZW50TGluZVN0YXJ0T2Zmc2V0OworICAgICAgICAgICAgbV90b2tlbi5tX2RhdGEubGlu
ZVN0YXJ0T2Zmc2V0ID0gY3VycmVudExpbmVTdGFydE9mZnNldDsKKyAgICAgICAgfQogCiAgICAg
ICAgIG1fbGV4ZXItPnNldE9mZnNldChtX3Rva2VuLm1fbG9jYXRpb24uZW5kT2Zmc2V0LCBtX3Rv
a2VuLm1fbG9jYXRpb24ubGluZVN0YXJ0T2Zmc2V0KTsKICAgICAgICAgbV9sZXhlci0+c2V0TGlu
ZU51bWJlcihtX3Rva2VuLm1fbG9jYXRpb24ubGluZSk7CkluZGV4OiBMYXlvdXRUZXN0cy9DaGFu
Z2VMb2cKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PQotLS0gTGF5b3V0VGVzdHMvQ2hhbmdlTG9nCShyZXZpc2lvbiAxNzgx
MzUpCisrKyBMYXlvdXRUZXN0cy9DaGFuZ2VMb2cJKHdvcmtpbmcgY29weSkKQEAgLTEsMyArMSwz
MyBAQAorMjAxNS0wMS0wOCAgTWljaGFlbCBTYWJvZmYgIDxtc2Fib2ZmQGFwcGxlLmNvbT4KKwor
ICAgICAgICBCcmVha3BvaW50IGRvZXNuJ3QgZmlyZSBpbiB0aGlzIEhUTUw1IGdhbWUKKyAgICAg
ICAgaHR0cHM6Ly9idWdzLndlYmtpdC5vcmcvc2hvd19idWcuY2dpP2lkPTE0MDI2OQorCisgICAg
ICAgIFJldmlld2VkIGJ5IE5PQk9EWSAoT09QUyEpLgorCisgICAgICAgIE5ldyB0ZXN0cyB0aGF0
IHNldCBicmVha3BvaW50cyBpbiBmdW5jdGlvbnMgd2l0aCB2YXJpb3VzIGxpbmUgc3BsaXQKKyAg
ICAgICAgY29tYmluYXRpb25zLgorCisgICAgICAgICogaW5zcGVjdG9yL2RlYnVnZ2VyL2JyZWFr
cG9pbnQtY29sdW1ucy1leHBlY3RlZC50eHQ6IEFkZGVkLgorICAgICAgICAqIGluc3BlY3Rvci9k
ZWJ1Z2dlci9icmVha3BvaW50LWNvbHVtbnMuaHRtbDogQWRkZWQuCisgICAgICAgICogaW5zcGVj
dG9yL2RlYnVnZ2VyL3Jlc291cmNlcy9jb2x1bW4tYnJlYWtwb2ludHMtMS5qczogQWRkZWQuCisg
ICAgICAgIChjb2x1bW5UZXN0MS54KToKKyAgICAgICAgKGNvbHVtblRlc3QxKToKKyAgICAgICAg
KGNvbHVtblRlc3QyLngpOgorICAgICAgICAoY29sdW1uVGVzdDIuZik6CisgICAgICAgIChjb2x1
bW5UZXN0My54KToKKyAgICAgICAgKGNvbHVtblRlc3QzLmYpOgorICAgICAgICAocnVuQ29sdW1u
VGVzdDEpOgorICAgICAgICAocnVuQ29sdW1uVGVzdDIpOgorICAgICAgICAocnVuQ29sdW1uVGVz
dDMpOgorICAgICAgICAqIGluc3BlY3Rvci9kZWJ1Z2dlci9yZXNvdXJjZXMvY29sdW1uLWJyZWFr
cG9pbnRzLTIuanM6IEFkZGVkLgorICAgICAgICAoY29sdW1uVGVzdDQueCk6CisgICAgICAgIChj
b2x1bW5UZXN0NC5mKToKKyAgICAgICAgKGNvbHVtblRlc3Q1LngpOgorICAgICAgICAoY29sdW1u
VGVzdDUpOgorICAgICAgICAocnVuQ29sdW1uVGVzdDQpOgorICAgICAgICAocnVuQ29sdW1uVGVz
dDUpOgorCiAyMDE1LTAxLTA4ICBEYXJpbiBBZGxlciAgPGRhcmluQGFwcGxlLmNvbT4KIAogICAg
ICAgICBBU1NFUlRJT04gRkFJTEVEOiBjaGFyYWN0ZXIgIT0ga0VuZE9mRmlsZU1hcmtlciBpbiBX
ZWJDb3JlOjpIVE1MVG9rZW5pemVyOjpidWZmZXJDaGFyYWN0ZXIKSW5kZXg6IExheW91dFRlc3Rz
L2luc3BlY3Rvci9kZWJ1Z2dlci9icmVha3BvaW50LWNvbHVtbnMtZXhwZWN0ZWQudHh0Cj09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT0KLS0tIExheW91dFRlc3RzL2luc3BlY3Rvci9kZWJ1Z2dlci9icmVha3BvaW50LWNvbHVt
bnMtZXhwZWN0ZWQudHh0CShyZXZpc2lvbiAwKQorKysgTGF5b3V0VGVzdHMvaW5zcGVjdG9yL2Rl
YnVnZ2VyL2JyZWFrcG9pbnQtY29sdW1ucy1leHBlY3RlZC50eHQJKHdvcmtpbmcgY29weSkKQEAg
LTAsMCArMSwxOSBAQAorQ09OU09MRSBNRVNTQUdFOiBsaW5lIDE6IFBhdXNlZCBhdCBsaW5lOiAw
LCBjb2x1bW46IDc5CitDT05TT0xFIE1FU1NBR0U6IGxpbmUgMTogY29sdW1uIHRlc3QgMQorQ09O
U09MRSBNRVNTQUdFOiBsaW5lIDE6IFBhdXNlZCBhdCBsaW5lOiA2LCBjb2x1bW46IDIxCitDT05T
T0xFIE1FU1NBR0U6IGxpbmUgNzogY29sdW1uIHRlc3QgMgorQ09OU09MRSBNRVNTQUdFOiBsaW5l
IDE6IFBhdXNlZCBhdCBsaW5lOiAxNSwgY29sdW1uOiA4CitDT05TT0xFIE1FU1NBR0U6IGxpbmUg
MTY6IGNvbHVtbiB0ZXN0IDMKK0NPTlNPTEUgTUVTU0FHRTogbGluZSAxOiBQYXVzZWQgYXQgbGlu
ZTogNSwgY29sdW1uOiA4CitDT05TT0xFIE1FU1NBR0U6IGxpbmUgNjogY29sdW1uIHRlc3QgNAor
Q09OU09MRSBNRVNTQUdFOiBsaW5lIDE6IFBhdXNlZCBhdCBsaW5lOiAxMSwgY29sdW1uOiA3OQor
Q09OU09MRSBNRVNTQUdFOiBsaW5lIDEyOiBjb2x1bW4gdGVzdCA1CitUZXN0aW5nIHRoYXQgYnJl
YWtwb2ludHMgY2FuIGJlIHNldCBhdCB2YXJpb3VzIGxpbmUgLyBjb2x1bW4gY29tYmluYXRpb25z
Jy4KKworSGl0IGJyZWFrcG9pbnQgYXQgbGluZTogMCwgY29sdW1uOiA3OQorSGl0IGJyZWFrcG9p
bnQgYXQgbGluZTogNiwgY29sdW1uOiAyMQorSGl0IGJyZWFrcG9pbnQgYXQgbGluZTogMTUsIGNv
bHVtbjogOAorSGl0IGJyZWFrcG9pbnQgYXQgbGluZTogNSwgY29sdW1uOiA4CitIaXQgYnJlYWtw
b2ludCBhdCBsaW5lOiAxMSwgY29sdW1uOiA3OQorVGVzdHMgZG9uZQorCkluZGV4OiBMYXlvdXRU
ZXN0cy9pbnNwZWN0b3IvZGVidWdnZXIvYnJlYWtwb2ludC1jb2x1bW5zLmh0bWwKPT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PQotLS0gTGF5b3V0VGVzdHMvaW5zcGVjdG9yL2RlYnVnZ2VyL2JyZWFrcG9pbnQtY29sdW1ucy5o
dG1sCShyZXZpc2lvbiAwKQorKysgTGF5b3V0VGVzdHMvaW5zcGVjdG9yL2RlYnVnZ2VyL2JyZWFr
cG9pbnQtY29sdW1ucy5odG1sCSh3b3JraW5nIGNvcHkpCkBAIC0wLDAgKzEsOTUgQEAKKzwhZG9j
dHlwZSBodG1sPgorPGh0bWw+Cis8aGVhZD4KKzxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0
IiBzcmM9Ii4uLy4uL2h0dHAvdGVzdHMvaW5zcGVjdG9yL2luc3BlY3Rvci10ZXN0LmpzIj48L3Nj
cmlwdD4KKzxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0IiBzcmM9Ii4uLy4uL2h0dHAvdGVz
dHMvaW5zcGVjdG9yL2RlYnVnZ2VyL2RlYnVnZ2VyLXRlc3QuanMiPjwvc2NyaXB0PgorPHNjcmlw
dCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0iLi9yZXNvdXJjZXMvY29sdW1uLWJyZWFrcG9p
bnRzLTEuanMiPjwvc2NyaXB0PgorPHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0i
Li9yZXNvdXJjZXMvY29sdW1uLWJyZWFrcG9pbnRzLTIuanMiPjwvc2NyaXB0PgorPHNjcmlwdD4K
KworZnVuY3Rpb24gdGVzdCgpCit7CisgICAgdmFyIHRlc3RJbmZvTGlzdCA9IFsKKyAgICAgICAg
eyBzY3JpcHRJbmRleCA6IDAsIGxpbmUgOiAwLCBjb2x1bW4gOiA3OSwgc3RhcnRGdW5jIDogInJ1
bkNvbHVtblRlc3QxKCkiIH0sCisgICAgICAgIHsgc2NyaXB0SW5kZXggOiAwLCBsaW5lIDogNiwg
Y29sdW1uIDogMjEsIHN0YXJ0RnVuYyA6ICJydW5Db2x1bW5UZXN0MigpIiB9LAorICAgICAgICB7
IHNjcmlwdEluZGV4IDogMCwgbGluZSA6IDE1LCBjb2x1bW4gOiA4LCBzdGFydEZ1bmMgOiAicnVu
Q29sdW1uVGVzdDMoKSIgfSwKKyAgICAgICAgeyBzY3JpcHRJbmRleCA6IDEsIGxpbmUgOiA1LCBj
b2x1bW4gOiA4LCBzdGFydEZ1bmMgOiAicnVuQ29sdW1uVGVzdDQoKSIgfSwKKyAgICAgICAgeyBz
Y3JpcHRJbmRleCA6IDEsIGxpbmUgOiAxMSwgY29sdW1uIDogNzksIHN0YXJ0RnVuYyA6ICJydW5D
b2x1bW5UZXN0NSgpIiB9CisgICAgXQorCisgICAgdmFyIGN1cnJlbnRUZXN0SW5kZXggPSAwOwor
ICAgIHZhciBzY3JpcHRPYmplY3QxLCBzY3JpcHRPYmplY3QyOworICAgIHZhciBjdXJyZW50U2Ny
aXB0cyA9IFtdOworCisgICAgZnVuY3Rpb24gcnVuTmV4dFRlc3RJZkFsbFNjcmlwdHNMb2FkZWQo
KSB7CisgICAgICAgIGlmIChzY3JpcHRPYmplY3QxICYmIHNjcmlwdE9iamVjdDIpIHsKKyAgICAg
ICAgICAgIGN1cnJlbnRTY3JpcHRzID0gW3NjcmlwdE9iamVjdDEsIHNjcmlwdE9iamVjdDJdOwor
ICAgICAgICAgICAgcnVuTmV4dFRlc3QoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIGZ1bmN0
aW9uIHJ1bk5leHRUZXN0KCkgeworICAgICAgICBpZiAoY3VycmVudFRlc3RJbmRleCA+PSB0ZXN0
SW5mb0xpc3QubGVuZ3RoKSB7CisgICAgICAgICAgICBJbnNwZWN0b3JUZXN0LmxvZygiVGVzdHMg
ZG9uZSIpOworICAgICAgICAgICAgSW5zcGVjdG9yVGVzdC5jb21wbGV0ZVRlc3QoKTsKKyAgICAg
ICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIHZhciB0ZXN0SW5mbyA9IHRlc3RJ
bmZvTGlzdFtjdXJyZW50VGVzdEluZGV4XTsKKyAgICAgICAgCisgICAgICAgIHZhciBsb2NhdGlv
biA9IGN1cnJlbnRTY3JpcHRzW3Rlc3RJbmZvLnNjcmlwdEluZGV4XS5jcmVhdGVTb3VyY2VDb2Rl
TG9jYXRpb24odGVzdEluZm8ubGluZSwgdGVzdEluZm8uY29sdW1uKTsKKyAgICAgICAgLy8gQ3Jl
YXRlIHRoZSBicmVha3BvaW50IGFuZCBpdHMgYWN0aW9ucyBiZWZvcmUgc2VuZGluZyBhbnl0aGlu
ZyB0byB0aGUgYmFja2VuZC4KKyAgICAgICAgdmFyIGJyZWFrcG9pbnQgPSBuZXcgV2ViSW5zcGVj
dG9yLkJyZWFrcG9pbnQobG9jYXRpb24pOworICAgICAgICBicmVha3BvaW50LmF1dG9Db250aW51
ZSA9IGZhbHNlOworCisgICAgICAgIFdlYkluc3BlY3Rvci5kZWJ1Z2dlck1hbmFnZXIuYWRkQnJl
YWtwb2ludChicmVha3BvaW50KTsKKworICAgICAgICBJbnNwZWN0b3JUZXN0LmV2YWx1YXRlSW5Q
YWdlKHRlc3RJbmZvLnN0YXJ0RnVuYyk7CisKKyAgICAgICAgY3VycmVudFRlc3RJbmRleCsrOwor
ICAgIH0gICAgICAgIAorCisgICAgV2ViSW5zcGVjdG9yLmRlYnVnZ2VyTWFuYWdlci5hZGRFdmVu
dExpc3RlbmVyKFdlYkluc3BlY3Rvci5EZWJ1Z2dlck1hbmFnZXIuRXZlbnQuQ2FsbEZyYW1lc0Rp
ZENoYW5nZSwKK2Z1bmN0aW9uKGV2ZW50KSB7CisgICAgICAgIGlmIChXZWJJbnNwZWN0b3IuZGVi
dWdnZXJNYW5hZ2VyLmFjdGl2ZUNhbGxGcmFtZSkgeworICAgICAgICAgICAgdmFyIHN0b3BMb2Nh
dGlvbiA9ICJsaW5lOiAiICsKKyAgICAgICAgICAgICAgICBXZWJJbnNwZWN0b3IuZGVidWdnZXJN
YW5hZ2VyLmFjdGl2ZUNhbGxGcmFtZS5zb3VyY2VDb2RlTG9jYXRpb24ubGluZU51bWJlciArCisg
ICAgICAgICAgICAgICAgIiwgY29sdW1uOiAiICsKKyAgICAgICAgICAgICAgICBXZWJJbnNwZWN0
b3IuZGVidWdnZXJNYW5hZ2VyLmFjdGl2ZUNhbGxGcmFtZS5zb3VyY2VDb2RlTG9jYXRpb24uY29s
dW1uTnVtYmVyOworCisgICAgICAgICAgICBJbnNwZWN0b3JUZXN0LmxvZygiSGl0IGJyZWFrcG9p
bnQgYXQgIiArIHN0b3BMb2NhdGlvbik7CisgICAgICAgICAgICBJbnNwZWN0b3JUZXN0LmV2YWx1
YXRlSW5QYWdlKCJjb25zb2xlLmxvZygnUGF1c2VkIGF0ICIgKyBzdG9wTG9jYXRpb24gKyAiJyki
KQorICAgICAgICB9CisKKyAgICAgICAgV2ViSW5zcGVjdG9yLmRlYnVnZ2VyTWFuYWdlci5yZXN1
bWUoKTsKKyAgICB9KTsKKworICAgIFdlYkluc3BlY3Rvci5kZWJ1Z2dlck1hbmFnZXIuYWRkRXZl
bnRMaXN0ZW5lcihXZWJJbnNwZWN0b3IuRGVidWdnZXJNYW5hZ2VyLkV2ZW50LlJlc3VtZWQsCitm
dW5jdGlvbihldmVudCkgeworICAgICAgIHJ1bk5leHRUZXN0KCk7CisgICAgfSk7CisKKyAgICBX
ZWJJbnNwZWN0b3IuZGVidWdnZXJNYW5hZ2VyLmFkZEV2ZW50TGlzdGVuZXIoV2ViSW5zcGVjdG9y
LkRlYnVnZ2VyTWFuYWdlci5FdmVudC5TY3JpcHRBZGRlZCwgZnVuY3Rpb24oZXZlbnQpIHsKKyAg
ICAgICAgdmFyIHNjcmlwdE9iamVjdCA9IGV2ZW50LmRhdGEuc2NyaXB0OworICAgICAgICAKKyAg
ICAgICAgaWYgKC9jb2x1bW4tYnJlYWtwb2ludHMtMVwuanMkLy50ZXN0KHNjcmlwdE9iamVjdC51
cmwpKSB7CisgICAgICAgICAgICBzY3JpcHRPYmplY3QxID0gc2NyaXB0T2JqZWN0OworICAgICAg
ICAgICAgcnVuTmV4dFRlc3RJZkFsbFNjcmlwdHNMb2FkZWQoKTsKKyAgICAgICAgICAgIHJldHVy
bjsKKyAgICAgICAgfQorCisgICAgICAgIGlmICgvY29sdW1uLWJyZWFrcG9pbnRzLTJcLmpzJC8u
dGVzdChzY3JpcHRPYmplY3QudXJsKSkgeworICAgICAgICAgICAgc2NyaXB0T2JqZWN0MiA9IHNj
cmlwdE9iamVjdDsKKyAgICAgICAgICAgIHJ1bk5leHRUZXN0SWZBbGxTY3JpcHRzTG9hZGVkKCk7
CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICB9KTsKKworICAgIEluc3BlY3Rv
clRlc3QucmVsb2FkUGFnZSgpOworfQorPC9zY3JpcHQ+Cis8L2hlYWQ+Cis8Ym9keSBvbmxvYWQ9
InJ1blRlc3QoKSI+CisgICAgPHA+VGVzdGluZyB0aGF0IGJyZWFrcG9pbnRzIGNhbiBiZSBzZXQg
YXQgdmFyaW91cyBsaW5lIC8gY29sdW1uIGNvbWJpbmF0aW9ucycuPC9wPgorPC9ib2R5PgorPC9o
dG1sPgpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKSW5kZXg6IExheW91dFRlc3RzL2luc3Bl
Y3Rvci9kZWJ1Z2dlci9yZXNvdXJjZXMvY29sdW1uLWJyZWFrcG9pbnRzLTEuanMKPT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PQotLS0gTGF5b3V0VGVzdHMvaW5zcGVjdG9yL2RlYnVnZ2VyL3Jlc291cmNlcy9jb2x1bW4tYnJl
YWtwb2ludHMtMS5qcwkocmV2aXNpb24gMCkKKysrIExheW91dFRlc3RzL2luc3BlY3Rvci9kZWJ1
Z2dlci9yZXNvdXJjZXMvY29sdW1uLWJyZWFrcG9pbnRzLTEuanMJKHdvcmtpbmcgY29weSkKQEAg
LTAsMCArMSwyNyBAQAorZnVuY3Rpb24gY29sdW1uVGVzdDEoKXt2YXIgeD1mdW5jdGlvbigpe3Nl
dEludGVydmFsKGZ1bmN0aW9uKCl7fSl9OyhmdW5jdGlvbigpe2NvbnNvbGUubG9nKCJjb2x1bW4g
dGVzdCAxIil9KSgpfQorLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICBicmVha3BvaW50IHNldCBoZXJlIF4gKDAsIDc5KQorCitmdW5jdGlv
biBjb2x1bW5UZXN0MigpCit7CisgICAgdmFyIHg9ZnVuY3Rpb24oKXtzZXRJbnRlcnZhbChmdW5j
dGlvbigpe30pfTsKKyAgICBmID0gZnVuY3Rpb24oKSB7IGNvbnNvbGUubG9nKCJjb2x1bW4gdGVz
dCAyIik7IH0oKTsKKy8vICAgICAgICAgICAgICAgICAgIF4gYnJlYWtwb2ludCBzZXQgaGVyZSAo
NiwgMjEpCit9CisKK2Z1bmN0aW9uIGNvbHVtblRlc3QzKCkKK3sKKyAgICB2YXIgeD1mdW5jdGlv
bigpe3NldEludGVydmFsKGZ1bmN0aW9uKCl7fSl9OworICAgIGYgPSBmdW5jdGlvbigpCisgICAg
eworICAgICAgICBjb25zb2xlLmxvZygiY29sdW1uIHRlc3QgMyIpOworLy8gICAgICBeIGJyZWFr
cG9pbnQgc2V0IGhlcmUgKDE1LCA4KQorICAgIH0KKyAgICBmKCk7Cit9CisKKy8vIEFueSBlZGl0
cyBvZiB0aGlzIGZpbGUgd2lsbCBuZWNlc3NpdGF0ZSBhIGNoYW5nZSB0byB0aGUgYnJlYWtwb2lu
dCAobGluZSwgY29sdW1uKSBjb29yZGluYXRlcworLy8gdXNlZCBpbiBicmVha3BvaW50LWNvbHVt
bnMuaHRtbC4KKworZnVuY3Rpb24gcnVuQ29sdW1uVGVzdDEoKSB7IHNldFRpbWVvdXQoY29sdW1u
VGVzdDEsIDApOyB9CitmdW5jdGlvbiBydW5Db2x1bW5UZXN0MigpIHsgc2V0VGltZW91dChjb2x1
bW5UZXN0MiwgMCk7IH0KK2Z1bmN0aW9uIHJ1bkNvbHVtblRlc3QzKCkgeyBzZXRUaW1lb3V0KGNv
bHVtblRlc3QzLCAwKTsgfQpJbmRleDogTGF5b3V0VGVzdHMvaW5zcGVjdG9yL2RlYnVnZ2VyL3Jl
c291cmNlcy9jb2x1bW4tYnJlYWtwb2ludHMtMi5qcwo9PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLSBMYXlvdXRUZXN0
cy9pbnNwZWN0b3IvZGVidWdnZXIvcmVzb3VyY2VzL2NvbHVtbi1icmVha3BvaW50cy0yLmpzCShy
ZXZpc2lvbiAwKQorKysgTGF5b3V0VGVzdHMvaW5zcGVjdG9yL2RlYnVnZ2VyL3Jlc291cmNlcy9j
b2x1bW4tYnJlYWtwb2ludHMtMi5qcwkod29ya2luZyBjb3B5KQpAQCAtMCwwICsxLDIwIEBACitm
dW5jdGlvbiBjb2x1bW5UZXN0NCgpCit7CisgICAgdmFyIHg9ZnVuY3Rpb24oKXtzZXRJbnRlcnZh
bChmdW5jdGlvbigpe30pfTsKKyAgICBmID0gZnVuY3Rpb24oKQorICAgIHsKKyAgICAgICAgY29u
c29sZS5sb2coImNvbHVtbiB0ZXN0IDQiKTsKKy8vICAgICAgXiBicmVha3BvaW50IHNldCBoZXJl
ICg1LCA4KQorICAgIH0KKyAgICBmKCk7Cit9CisKK2Z1bmN0aW9uIGNvbHVtblRlc3Q1KCl7dmFy
IHg9ZnVuY3Rpb24oKXtzZXRJbnRlcnZhbChmdW5jdGlvbigpe30pfTsoZnVuY3Rpb24oKXtjb25z
b2xlLmxvZygiY29sdW1uIHRlc3QgNSIpfSkoKX0KKy8vICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWtwb2ludCBzZXQgaGVyZSBeICgx
MSwgNzkpCisKKworLy8gQW55IGVkaXRzIG9mIHRoaXMgZmlsZSB3aWxsIG5lY2Vzc2l0YXRlIGEg
Y2hhbmdlIHRvIHRoZSBicmVha3BvaW50IChsaW5lLCBjb2x1bW4pIGNvb3JkaW5hdGVzCisvLyB1
c2VkIGluIGJyZWFrcG9pbnQtY29sdW1ucy5odG1sLgorCitmdW5jdGlvbiBydW5Db2x1bW5UZXN0
NCgpIHsgc2V0VGltZW91dChjb2x1bW5UZXN0NCwgMCk7IH0KK2Z1bmN0aW9uIHJ1bkNvbHVtblRl
c3Q1KCkgeyBzZXRUaW1lb3V0KGNvbHVtblRlc3Q1LCAwKTsgfQo=
</data>

          </attachment>
          <attachment
              isobsolete="0"
              ispatch="1"
              isprivate="0"
          >
            <attachid>244309</attachid>
            <date>2015-01-08 16:12:23 -0800</date>
            <delta_ts>2015-01-09 16:24:59 -0800</delta_ts>
            <desc>Patch with reviewer&apos;s suggested changes.</desc>
            <filename>140269-2.patch</filename>
            <type>text/plain</type>
            <size>10474</size>
            <attacher name="Michael Saboff">msaboff</attacher>
            
              <data encoding="base64">SW5kZXg6IFNvdXJjZS9KYXZhU2NyaXB0Q29yZS9DaGFuZ2VMb2cKPT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0gU291
cmNlL0phdmFTY3JpcHRDb3JlL0NoYW5nZUxvZwkocmV2aXNpb24gMTc4MTM1KQorKysgU291cmNl
L0phdmFTY3JpcHRDb3JlL0NoYW5nZUxvZwkod29ya2luZyBjb3B5KQpAQCAtMSwzICsxLDE4IEBA
CisyMDE1LTAxLTA4ICBNaWNoYWVsIFNhYm9mZiAgPG1zYWJvZmZAYXBwbGUuY29tPgorCisgICAg
ICAgIEJyZWFrcG9pbnQgZG9lc24ndCBmaXJlIGluIHRoaXMgSFRNTDUgZ2FtZQorICAgICAgICBo
dHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTQwMjY5CisKKyAgICAgICAg
UmV2aWV3ZWQgYnkgTk9CT0RZIChPT1BTISkuCisKKyAgICAgICAgV2hlbiBwYXJzaW5nIGEgc2lu
Z2xlIGxpbmUgY2FjaGVkIGZ1bmN0aW9uLCB1c2UgdGhlIGxpbmVTdGFydE9mZnNldCBvZiB0aGUK
KyAgICAgICAgbG9jYXRpb24gd2hlcmUgd2UgZm91bmQgdGhlIGNhY2hlZCBmdW5jdGlvbiBpbnN0
ZWFkIG9mIHRoZSBjYWNoZWQgbGluZVN0YXJ0T2Zmc2V0LgorICAgICAgICBUaGUgY2FjaGUgbG9j
YXRpb24ncyBsaW5lU3RhcnRPZmZzZXQgaGFzIG5vdCBiZWVuIGFkanVzdGVkIGZvciBhbnkgcG9z
c2libGUKKyAgICAgICAgY29udGFpbmluZyBmdW5jdGlvbnMuCisKKyAgICAgICAgKiBwYXJzZXIv
UGFyc2VyLmNwcDoKKyAgICAgICAgKEpTQzo6UGFyc2VyPExleGVyVHlwZT46OnBhcnNlRnVuY3Rp
b25JbmZvKToKKwogMjAxNS0wMS0wOCAgSm9zZXBoIFBlY29yYXJvICA8cGVjb3Jhcm9AYXBwbGUu
Y29tPgogCiAgICAgICAgIFdlYiBJbnNwZWN0b3I6IFR5cGUgY2hlY2sgTlNBcnJheSdzIGluIE9i
akMgSW50ZXJmYWNlcyBoYXZlIHRoZSByaWdodCBvYmplY3QgdHlwZXMKSW5kZXg6IFNvdXJjZS9K
YXZhU2NyaXB0Q29yZS9wYXJzZXIvUGFyc2VyLmNwcAo9PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLSBTb3VyY2UvSmF2
YVNjcmlwdENvcmUvcGFyc2VyL1BhcnNlci5jcHAJKHJldmlzaW9uIDE3ODEyMSkKKysrIFNvdXJj
ZS9KYXZhU2NyaXB0Q29yZS9wYXJzZXIvUGFyc2VyLmNwcAkod29ya2luZyBjb3B5KQpAQCAtMTMy
NCw2ICsxMzI0LDcgQEAgdGVtcGxhdGUgPGNsYXNzIFRyZWVCdWlsZGVyPiBib29sIFBhcnNlcgog
ICAgICAgICB1bnNpZ25lZCBib2R5RW5kQ29sdW1uID0gZW5kQ29sdW1uSXNPblN0YXJ0TGluZSA/
CiAgICAgICAgICAgICBlbmRMb2NhdGlvbi5zdGFydE9mZnNldCAtIG1fdG9rZW4ubV9kYXRhLmxp
bmVTdGFydE9mZnNldCA6CiAgICAgICAgICAgICBlbmRMb2NhdGlvbi5zdGFydE9mZnNldCAtIGVu
ZExvY2F0aW9uLmxpbmVTdGFydE9mZnNldDsKKyAgICAgICAgdW5zaWduZWQgY3VycmVudExpbmVT
dGFydE9mZnNldCA9IG1fdG9rZW4ubV9sb2NhdGlvbi5saW5lU3RhcnRPZmZzZXQ7CiAKICAgICAg
ICAgYm9keSA9IGNvbnRleHQuY3JlYXRlRnVuY3Rpb25Cb2R5KHN0YXJ0TG9jYXRpb24sIGVuZExv
Y2F0aW9uLCBib2R5U3RhcnRDb2x1bW4sIGJvZHlFbmRDb2x1bW4sIGNhY2hlZEluZm8tPnN0cmlj
dE1vZGUpOwogICAgICAgICAKQEAgLTEzMzQsNiArMTMzNSwxMCBAQCB0ZW1wbGF0ZSA8Y2xhc3Mg
VHJlZUJ1aWxkZXI+IGJvb2wgUGFyc2VyCiAKICAgICAgICAgY29udGV4dC5zZXRGdW5jdGlvbk5h
bWVTdGFydChib2R5LCBmdW5jdGlvbk5hbWVTdGFydCk7CiAgICAgICAgIG1fdG9rZW4gPSBjYWNo
ZWRJbmZvLT5jbG9zZUJyYWNlVG9rZW4oKTsKKyAgICAgICAgaWYgKGVuZENvbHVtbklzT25TdGFy
dExpbmUpIHsKKyAgICAgICAgICAgIG1fdG9rZW4ubV9sb2NhdGlvbi5saW5lU3RhcnRPZmZzZXQg
PSBjdXJyZW50TGluZVN0YXJ0T2Zmc2V0OworICAgICAgICAgICAgbV90b2tlbi5tX2RhdGEubGlu
ZVN0YXJ0T2Zmc2V0ID0gY3VycmVudExpbmVTdGFydE9mZnNldDsKKyAgICAgICAgfQogCiAgICAg
ICAgIG1fbGV4ZXItPnNldE9mZnNldChtX3Rva2VuLm1fbG9jYXRpb24uZW5kT2Zmc2V0LCBtX3Rv
a2VuLm1fbG9jYXRpb24ubGluZVN0YXJ0T2Zmc2V0KTsKICAgICAgICAgbV9sZXhlci0+c2V0TGlu
ZU51bWJlcihtX3Rva2VuLm1fbG9jYXRpb24ubGluZSk7CkluZGV4OiBMYXlvdXRUZXN0cy9DaGFu
Z2VMb2cKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PQotLS0gTGF5b3V0VGVzdHMvQ2hhbmdlTG9nCShyZXZpc2lvbiAxNzgx
MzUpCisrKyBMYXlvdXRUZXN0cy9DaGFuZ2VMb2cJKHdvcmtpbmcgY29weSkKQEAgLTEsMyArMSwz
MyBAQAorMjAxNS0wMS0wOCAgTWljaGFlbCBTYWJvZmYgIDxtc2Fib2ZmQGFwcGxlLmNvbT4KKwor
ICAgICAgICBCcmVha3BvaW50IGRvZXNuJ3QgZmlyZSBpbiB0aGlzIEhUTUw1IGdhbWUKKyAgICAg
ICAgaHR0cHM6Ly9idWdzLndlYmtpdC5vcmcvc2hvd19idWcuY2dpP2lkPTE0MDI2OQorCisgICAg
ICAgIFJldmlld2VkIGJ5IE5PQk9EWSAoT09QUyEpLgorCisgICAgICAgIE5ldyB0ZXN0cyB0aGF0
IHNldCBicmVha3BvaW50cyBpbiBmdW5jdGlvbnMgd2l0aCB2YXJpb3VzIGxpbmUgc3BsaXQKKyAg
ICAgICAgY29tYmluYXRpb25zLgorCisgICAgICAgICogaW5zcGVjdG9yL2RlYnVnZ2VyL2JyZWFr
cG9pbnQtY29sdW1ucy1leHBlY3RlZC50eHQ6IEFkZGVkLgorICAgICAgICAqIGluc3BlY3Rvci9k
ZWJ1Z2dlci9icmVha3BvaW50LWNvbHVtbnMuaHRtbDogQWRkZWQuCisgICAgICAgICogaW5zcGVj
dG9yL2RlYnVnZ2VyL3Jlc291cmNlcy9jb2x1bW4tYnJlYWtwb2ludHMtMS5qczogQWRkZWQuCisg
ICAgICAgIChjb2x1bW5UZXN0MS54KToKKyAgICAgICAgKGNvbHVtblRlc3QxKToKKyAgICAgICAg
KGNvbHVtblRlc3QyLngpOgorICAgICAgICAoY29sdW1uVGVzdDIuZik6CisgICAgICAgIChjb2x1
bW5UZXN0My54KToKKyAgICAgICAgKGNvbHVtblRlc3QzLmYpOgorICAgICAgICAocnVuQ29sdW1u
VGVzdDEpOgorICAgICAgICAocnVuQ29sdW1uVGVzdDIpOgorICAgICAgICAocnVuQ29sdW1uVGVz
dDMpOgorICAgICAgICAqIGluc3BlY3Rvci9kZWJ1Z2dlci9yZXNvdXJjZXMvY29sdW1uLWJyZWFr
cG9pbnRzLTIuanM6IEFkZGVkLgorICAgICAgICAoY29sdW1uVGVzdDQueCk6CisgICAgICAgIChj
b2x1bW5UZXN0NC5mKToKKyAgICAgICAgKGNvbHVtblRlc3Q1LngpOgorICAgICAgICAoY29sdW1u
VGVzdDUpOgorICAgICAgICAocnVuQ29sdW1uVGVzdDQpOgorICAgICAgICAocnVuQ29sdW1uVGVz
dDUpOgorCiAyMDE1LTAxLTA4ICBEYXJpbiBBZGxlciAgPGRhcmluQGFwcGxlLmNvbT4KIAogICAg
ICAgICBBU1NFUlRJT04gRkFJTEVEOiBjaGFyYWN0ZXIgIT0ga0VuZE9mRmlsZU1hcmtlciBpbiBX
ZWJDb3JlOjpIVE1MVG9rZW5pemVyOjpidWZmZXJDaGFyYWN0ZXIKSW5kZXg6IExheW91dFRlc3Rz
L2luc3BlY3Rvci9kZWJ1Z2dlci9icmVha3BvaW50LWNvbHVtbnMtZXhwZWN0ZWQudHh0Cj09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT0KLS0tIExheW91dFRlc3RzL2luc3BlY3Rvci9kZWJ1Z2dlci9icmVha3BvaW50LWNvbHVt
bnMtZXhwZWN0ZWQudHh0CShyZXZpc2lvbiAwKQorKysgTGF5b3V0VGVzdHMvaW5zcGVjdG9yL2Rl
YnVnZ2VyL2JyZWFrcG9pbnQtY29sdW1ucy1leHBlY3RlZC50eHQJKHdvcmtpbmcgY29weSkKQEAg
LTAsMCArMSwxOSBAQAorQ09OU09MRSBNRVNTQUdFOiBsaW5lIDE6IFBhdXNlZCBhdCBsaW5lOiAw
LCBjb2x1bW46IDc5CitDT05TT0xFIE1FU1NBR0U6IGxpbmUgMTogY29sdW1uIHRlc3QgMQorQ09O
U09MRSBNRVNTQUdFOiBsaW5lIDE6IFBhdXNlZCBhdCBsaW5lOiA2LCBjb2x1bW46IDIxCitDT05T
T0xFIE1FU1NBR0U6IGxpbmUgNzogY29sdW1uIHRlc3QgMgorQ09OU09MRSBNRVNTQUdFOiBsaW5l
IDE6IFBhdXNlZCBhdCBsaW5lOiAxNSwgY29sdW1uOiA4CitDT05TT0xFIE1FU1NBR0U6IGxpbmUg
MTY6IGNvbHVtbiB0ZXN0IDMKK0NPTlNPTEUgTUVTU0FHRTogbGluZSAxOiBQYXVzZWQgYXQgbGlu
ZTogNSwgY29sdW1uOiA4CitDT05TT0xFIE1FU1NBR0U6IGxpbmUgNjogY29sdW1uIHRlc3QgNAor
Q09OU09MRSBNRVNTQUdFOiBsaW5lIDE6IFBhdXNlZCBhdCBsaW5lOiAxMSwgY29sdW1uOiA3OQor
Q09OU09MRSBNRVNTQUdFOiBsaW5lIDEyOiBjb2x1bW4gdGVzdCA1CitUZXN0aW5nIHRoYXQgYnJl
YWtwb2ludHMgY2FuIGJlIHNldCBhdCB2YXJpb3VzIGxpbmUgLyBjb2x1bW4gY29tYmluYXRpb25z
LgorCitIaXQgYnJlYWtwb2ludCBhdCBsaW5lOiAwLCBjb2x1bW46IDc5CitIaXQgYnJlYWtwb2lu
dCBhdCBsaW5lOiA2LCBjb2x1bW46IDIxCitIaXQgYnJlYWtwb2ludCBhdCBsaW5lOiAxNSwgY29s
dW1uOiA4CitIaXQgYnJlYWtwb2ludCBhdCBsaW5lOiA1LCBjb2x1bW46IDgKK0hpdCBicmVha3Bv
aW50IGF0IGxpbmU6IDExLCBjb2x1bW46IDc5CitUZXN0cyBkb25lCisKSW5kZXg6IExheW91dFRl
c3RzL2luc3BlY3Rvci9kZWJ1Z2dlci9icmVha3BvaW50LWNvbHVtbnMuaHRtbAo9PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
Ci0tLSBMYXlvdXRUZXN0cy9pbnNwZWN0b3IvZGVidWdnZXIvYnJlYWtwb2ludC1jb2x1bW5zLmh0
bWwJKHJldmlzaW9uIDApCisrKyBMYXlvdXRUZXN0cy9pbnNwZWN0b3IvZGVidWdnZXIvYnJlYWtw
b2ludC1jb2x1bW5zLmh0bWwJKHdvcmtpbmcgY29weSkKQEAgLTAsMCArMSw5MSBAQAorPCFkb2N0
eXBlIGh0bWw+Cis8aHRtbD4KKzxoZWFkPgorPHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQi
IHNyYz0iLi4vLi4vaHR0cC90ZXN0cy9pbnNwZWN0b3IvaW5zcGVjdG9yLXRlc3QuanMiPjwvc2Ny
aXB0PgorPHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0iLi4vLi4vaHR0cC90ZXN0
cy9pbnNwZWN0b3IvZGVidWdnZXIvZGVidWdnZXItdGVzdC5qcyI+PC9zY3JpcHQ+Cis8c2NyaXB0
IHR5cGU9InRleHQvamF2YXNjcmlwdCIgc3JjPSIuL3Jlc291cmNlcy9jb2x1bW4tYnJlYWtwb2lu
dHMtMS5qcyI+PC9zY3JpcHQ+Cis8c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCIgc3JjPSIu
L3Jlc291cmNlcy9jb2x1bW4tYnJlYWtwb2ludHMtMi5qcyI+PC9zY3JpcHQ+Cis8c2NyaXB0Pgor
CitmdW5jdGlvbiB0ZXN0KCkKK3sKKyAgICB2YXIgdGVzdEluZm9MaXN0ID0gWworICAgICAgICB7
IHNjcmlwdEluZGV4IDogMCwgbGluZSA6IDAsIGNvbHVtbiA6IDc5LCBzdGFydEZ1bmMgOiAicnVu
Q29sdW1uVGVzdDEoKSIgfSwKKyAgICAgICAgeyBzY3JpcHRJbmRleCA6IDAsIGxpbmUgOiA2LCBj
b2x1bW4gOiAyMSwgc3RhcnRGdW5jIDogInJ1bkNvbHVtblRlc3QyKCkiIH0sCisgICAgICAgIHsg
c2NyaXB0SW5kZXggOiAwLCBsaW5lIDogMTUsIGNvbHVtbiA6IDgsIHN0YXJ0RnVuYyA6ICJydW5D
b2x1bW5UZXN0MygpIiB9LAorICAgICAgICB7IHNjcmlwdEluZGV4IDogMSwgbGluZSA6IDUsIGNv
bHVtbiA6IDgsIHN0YXJ0RnVuYyA6ICJydW5Db2x1bW5UZXN0NCgpIiB9LAorICAgICAgICB7IHNj
cmlwdEluZGV4IDogMSwgbGluZSA6IDExLCBjb2x1bW4gOiA3OSwgc3RhcnRGdW5jIDogInJ1bkNv
bHVtblRlc3Q1KCkiIH0KKyAgICBdCisKKyAgICB2YXIgY3VycmVudFRlc3RJbmRleCA9IDA7Cisg
ICAgdmFyIHNjcmlwdE9iamVjdDEsIHNjcmlwdE9iamVjdDI7CisgICAgdmFyIGN1cnJlbnRTY3Jp
cHRzID0gW107CisKKyAgICBmdW5jdGlvbiBydW5OZXh0VGVzdElmQWxsU2NyaXB0c0xvYWRlZCgp
IHsKKyAgICAgICAgaWYgKHNjcmlwdE9iamVjdDEgJiYgc2NyaXB0T2JqZWN0MikgeworICAgICAg
ICAgICAgY3VycmVudFNjcmlwdHMgPSBbc2NyaXB0T2JqZWN0MSwgc2NyaXB0T2JqZWN0Ml07Cisg
ICAgICAgICAgICBydW5OZXh0VGVzdCgpOworICAgICAgICB9CisgICAgfQorCisgICAgZnVuY3Rp
b24gcnVuTmV4dFRlc3QoKSB7CisgICAgICAgIGlmIChjdXJyZW50VGVzdEluZGV4ID49IHRlc3RJ
bmZvTGlzdC5sZW5ndGgpIHsKKyAgICAgICAgICAgIEluc3BlY3RvclRlc3QubG9nKCJUZXN0cyBk
b25lIik7CisgICAgICAgICAgICBJbnNwZWN0b3JUZXN0LmNvbXBsZXRlVGVzdCgpOworICAgICAg
ICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICAgICAgdmFyIHRlc3RJbmZvID0gdGVzdElu
Zm9MaXN0W2N1cnJlbnRUZXN0SW5kZXhdOworICAgICAgICAKKyAgICAgICAgdmFyIGxvY2F0aW9u
ID0gY3VycmVudFNjcmlwdHNbdGVzdEluZm8uc2NyaXB0SW5kZXhdLmNyZWF0ZVNvdXJjZUNvZGVM
b2NhdGlvbih0ZXN0SW5mby5saW5lLCB0ZXN0SW5mby5jb2x1bW4pOworICAgICAgICB2YXIgYnJl
YWtwb2ludCA9IG5ldyBXZWJJbnNwZWN0b3IuQnJlYWtwb2ludChsb2NhdGlvbik7CisKKyAgICAg
ICAgV2ViSW5zcGVjdG9yLmRlYnVnZ2VyTWFuYWdlci5hZGRCcmVha3BvaW50KGJyZWFrcG9pbnQp
OworCisgICAgICAgIEluc3BlY3RvclRlc3QuZXZhbHVhdGVJblBhZ2UodGVzdEluZm8uc3RhcnRG
dW5jKTsKKworICAgICAgICBjdXJyZW50VGVzdEluZGV4Kys7CisgICAgfSAgICAgICAgCisKKyAg
ICBXZWJJbnNwZWN0b3IuZGVidWdnZXJNYW5hZ2VyLmFkZEV2ZW50TGlzdGVuZXIoV2ViSW5zcGVj
dG9yLkRlYnVnZ2VyTWFuYWdlci5FdmVudC5DYWxsRnJhbWVzRGlkQ2hhbmdlLCBmdW5jdGlvbihl
dmVudCkgeworICAgICAgICB2YXIgYWN0aXZlQ2FsbEZyYW1lID0gV2ViSW5zcGVjdG9yLmRlYnVn
Z2VyTWFuYWdlci5hY3RpdmVDYWxsRnJhbWU7CisKKyAgICAgICAgaWYgKCFhY3RpdmVDYWxsRnJh
bWUpCisgICAgICAgICAgICByZXR1cm47CisKKyAgICAgICAgdmFyIHN0b3BMb2NhdGlvbiA9ICJs
aW5lOiAiICsgYWN0aXZlQ2FsbEZyYW1lLnNvdXJjZUNvZGVMb2NhdGlvbi5saW5lTnVtYmVyICsg
IiwgY29sdW1uOiAiICsgYWN0aXZlQ2FsbEZyYW1lLnNvdXJjZUNvZGVMb2NhdGlvbi5jb2x1bW5O
dW1iZXI7CisKKyAgICAgICAgSW5zcGVjdG9yVGVzdC5sb2coIkhpdCBicmVha3BvaW50IGF0ICIg
KyBzdG9wTG9jYXRpb24pOworICAgICAgICBJbnNwZWN0b3JUZXN0LmV2YWx1YXRlSW5QYWdlKCJj
b25zb2xlLmxvZygnUGF1c2VkIGF0ICIgKyBzdG9wTG9jYXRpb24gKyAiJykiKTsKKworICAgICAg
ICBXZWJJbnNwZWN0b3IuZGVidWdnZXJNYW5hZ2VyLnJlc3VtZSgpOworICAgIH0pOworCisgICAg
V2ViSW5zcGVjdG9yLmRlYnVnZ2VyTWFuYWdlci5hZGRFdmVudExpc3RlbmVyKFdlYkluc3BlY3Rv
ci5EZWJ1Z2dlck1hbmFnZXIuRXZlbnQuUmVzdW1lZCwgZnVuY3Rpb24oZXZlbnQpIHsKKyAgICAg
ICBydW5OZXh0VGVzdCgpOworICAgIH0pOworCisgICAgV2ViSW5zcGVjdG9yLmRlYnVnZ2VyTWFu
YWdlci5hZGRFdmVudExpc3RlbmVyKFdlYkluc3BlY3Rvci5EZWJ1Z2dlck1hbmFnZXIuRXZlbnQu
U2NyaXB0QWRkZWQsIGZ1bmN0aW9uKGV2ZW50KSB7CisgICAgICAgIHZhciBzY3JpcHRPYmplY3Qg
PSBldmVudC5kYXRhLnNjcmlwdDsKKyAgICAgICAgCisgICAgICAgIGlmICgvY29sdW1uLWJyZWFr
cG9pbnRzLTFcLmpzJC8udGVzdChzY3JpcHRPYmplY3QudXJsKSkgeworICAgICAgICAgICAgc2Ny
aXB0T2JqZWN0MSA9IHNjcmlwdE9iamVjdDsKKyAgICAgICAgICAgIHJ1bk5leHRUZXN0SWZBbGxT
Y3JpcHRzTG9hZGVkKCk7CisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKworICAgICAg
ICBpZiAoL2NvbHVtbi1icmVha3BvaW50cy0yXC5qcyQvLnRlc3Qoc2NyaXB0T2JqZWN0LnVybCkp
IHsKKyAgICAgICAgICAgIHNjcmlwdE9iamVjdDIgPSBzY3JpcHRPYmplY3Q7CisgICAgICAgICAg
ICBydW5OZXh0VGVzdElmQWxsU2NyaXB0c0xvYWRlZCgpOworICAgICAgICAgICAgcmV0dXJuOwor
ICAgICAgICB9CisgICAgfSk7CisKKyAgICBJbnNwZWN0b3JUZXN0LnJlbG9hZFBhZ2UoKTsKK30K
Kzwvc2NyaXB0PgorPC9oZWFkPgorPGJvZHkgb25sb2FkPSJydW5UZXN0KCkiPgorICAgIDxwPlRl
c3RpbmcgdGhhdCBicmVha3BvaW50cyBjYW4gYmUgc2V0IGF0IHZhcmlvdXMgbGluZSAvIGNvbHVt
biBjb21iaW5hdGlvbnMuPC9wPgorPC9ib2R5PgorPC9odG1sPgpJbmRleDogTGF5b3V0VGVzdHMv
aW5zcGVjdG9yL2RlYnVnZ2VyL3Jlc291cmNlcy9jb2x1bW4tYnJlYWtwb2ludHMtMS5qcwo9PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09Ci0tLSBMYXlvdXRUZXN0cy9pbnNwZWN0b3IvZGVidWdnZXIvcmVzb3VyY2VzL2NvbHVt
bi1icmVha3BvaW50cy0xLmpzCShyZXZpc2lvbiAwKQorKysgTGF5b3V0VGVzdHMvaW5zcGVjdG9y
L2RlYnVnZ2VyL3Jlc291cmNlcy9jb2x1bW4tYnJlYWtwb2ludHMtMS5qcwkod29ya2luZyBjb3B5
KQpAQCAtMCwwICsxLDI3IEBACitmdW5jdGlvbiBjb2x1bW5UZXN0MSgpe3ZhciB4PWZ1bmN0aW9u
KCl7c2V0SW50ZXJ2YWwoZnVuY3Rpb24oKXt9KX07KGZ1bmN0aW9uKCl7Y29uc29sZS5sb2coImNv
bHVtbiB0ZXN0IDEiKX0pKCl9CisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgIGJyZWFrcG9pbnQgc2V0IGhlcmUgXiAoMCwgNzkpCisKK2Z1
bmN0aW9uIGNvbHVtblRlc3QyKCkKK3sKKyAgICB2YXIgeD1mdW5jdGlvbigpe3NldEludGVydmFs
KGZ1bmN0aW9uKCl7fSl9OworICAgIGYgPSBmdW5jdGlvbigpIHsgY29uc29sZS5sb2coImNvbHVt
biB0ZXN0IDIiKTsgfSgpOworLy8gICAgICAgICAgICAgICAgICAgXiBicmVha3BvaW50IHNldCBo
ZXJlICg2LCAyMSkKK30KKworZnVuY3Rpb24gY29sdW1uVGVzdDMoKQoreworICAgIHZhciB4PWZ1
bmN0aW9uKCl7c2V0SW50ZXJ2YWwoZnVuY3Rpb24oKXt9KX07CisgICAgZiA9IGZ1bmN0aW9uKCkK
KyAgICB7CisgICAgICAgIGNvbnNvbGUubG9nKCJjb2x1bW4gdGVzdCAzIik7CisvLyAgICAgIF4g
YnJlYWtwb2ludCBzZXQgaGVyZSAoMTUsIDgpCisgICAgfQorICAgIGYoKTsKK30KKworLy8gQW55
IGVkaXRzIG9mIHRoaXMgZmlsZSB3aWxsIG5lY2Vzc2l0YXRlIGEgY2hhbmdlIHRvIHRoZSBicmVh
a3BvaW50IChsaW5lLCBjb2x1bW4pIGNvb3JkaW5hdGVzCisvLyB1c2VkIGluIGJyZWFrcG9pbnQt
Y29sdW1ucy5odG1sLgorCitmdW5jdGlvbiBydW5Db2x1bW5UZXN0MSgpIHsgc2V0VGltZW91dChj
b2x1bW5UZXN0MSwgMCk7IH0KK2Z1bmN0aW9uIHJ1bkNvbHVtblRlc3QyKCkgeyBzZXRUaW1lb3V0
KGNvbHVtblRlc3QyLCAwKTsgfQorZnVuY3Rpb24gcnVuQ29sdW1uVGVzdDMoKSB7IHNldFRpbWVv
dXQoY29sdW1uVGVzdDMsIDApOyB9CkluZGV4OiBMYXlvdXRUZXN0cy9pbnNwZWN0b3IvZGVidWdn
ZXIvcmVzb3VyY2VzL2NvbHVtbi1icmVha3BvaW50cy0yLmpzCj09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tIExheW91
dFRlc3RzL2luc3BlY3Rvci9kZWJ1Z2dlci9yZXNvdXJjZXMvY29sdW1uLWJyZWFrcG9pbnRzLTIu
anMJKHJldmlzaW9uIDApCisrKyBMYXlvdXRUZXN0cy9pbnNwZWN0b3IvZGVidWdnZXIvcmVzb3Vy
Y2VzL2NvbHVtbi1icmVha3BvaW50cy0yLmpzCSh3b3JraW5nIGNvcHkpCkBAIC0wLDAgKzEsMjAg
QEAKK2Z1bmN0aW9uIGNvbHVtblRlc3Q0KCkKK3sKKyAgICB2YXIgeD1mdW5jdGlvbigpe3NldElu
dGVydmFsKGZ1bmN0aW9uKCl7fSl9OworICAgIGYgPSBmdW5jdGlvbigpCisgICAgeworICAgICAg
ICBjb25zb2xlLmxvZygiY29sdW1uIHRlc3QgNCIpOworLy8gICAgICBeIGJyZWFrcG9pbnQgc2V0
IGhlcmUgKDUsIDgpCisgICAgfQorICAgIGYoKTsKK30KKworZnVuY3Rpb24gY29sdW1uVGVzdDUo
KXt2YXIgeD1mdW5jdGlvbigpe3NldEludGVydmFsKGZ1bmN0aW9uKCl7fSl9OyhmdW5jdGlvbigp
e2NvbnNvbGUubG9nKCJjb2x1bW4gdGVzdCA1Iil9KSgpfQorLy8gICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVha3BvaW50IHNldCBoZXJl
IF4gKDExLCA3OSkKKworCisvLyBBbnkgZWRpdHMgb2YgdGhpcyBmaWxlIHdpbGwgbmVjZXNzaXRh
dGUgYSBjaGFuZ2UgdG8gdGhlIGJyZWFrcG9pbnQgKGxpbmUsIGNvbHVtbikgY29vcmRpbmF0ZXMK
Ky8vIHVzZWQgaW4gYnJlYWtwb2ludC1jb2x1bW5zLmh0bWwuCisKK2Z1bmN0aW9uIHJ1bkNvbHVt
blRlc3Q0KCkgeyBzZXRUaW1lb3V0KGNvbHVtblRlc3Q0LCAwKTsgfQorZnVuY3Rpb24gcnVuQ29s
dW1uVGVzdDUoKSB7IHNldFRpbWVvdXQoY29sdW1uVGVzdDUsIDApOyB9Cg==
</data>
<flag name="review"
          id="269234"
          type_id="1"
          status="+"
          setter="mark.lam"
    />
          </attachment>
      

    </bug>

</bugzilla>