<?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>224749</bug_id>
          
          <creation_ts>2021-04-19 05:05:59 -0700</creation_ts>
          <short_desc>Don&apos;t use the full CSS parser for CSSFontFaceSet</short_desc>
          <delta_ts>2021-04-23 02:54:08 -0700</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>WebKit</product>
          <component>CSS</component>
          <version>WebKit Nightly Build</version>
          <rep_platform>Unspecified</rep_platform>
          <op_sys>Unspecified</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>
          
          <blocked>224178</blocked>
          <everconfirmed>1</everconfirmed>
          <reporter name="Chris Lord">clord</reporter>
          <assigned_to name="Chris Lord">clord</assigned_to>
          <cc>darin</cc>
    
    <cc>esprehn+autocc</cc>
    
    <cc>ews-watchlist</cc>
    
    <cc>glenn</cc>
    
    <cc>gyuyoung.kim</cc>
    
    <cc>lingcherd_ho</cc>
    
    <cc>macpherson</cc>
    
    <cc>menard</cc>
    
    <cc>mmaxfield</cc>
    
    <cc>rniwa</cc>
    
    <cc>svillar</cc>
    
    <cc>webkit-bug-importer</cc>
          

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>1751737</commentid>
    <comment_count>0</comment_count>
    <who name="Chris Lord">clord</who>
    <bug_when>2021-04-19 05:05:59 -0700</bug_when>
    <thetext>Currently, CSSFontFaceSet uses the full CSS parser and relies on CSSValuePool::singleton(). This makes it not immediately viable to use in a Worker, but is also probably overkill - like Canvas and OffscreenCanvas, I think CSSFontFaceSet could just use FontRaw, which would kill two birds with one stone - it&apos;d be both faster and worker-safe.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1751747</commentid>
    <comment_count>1</comment_count>
      <attachid>426410</attachid>
    <who name="Chris Lord">clord</who>
    <bug_when>2021-04-19 05:44:44 -0700</bug_when>
    <thetext>Created attachment 426410
Patch</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1751971</commentid>
    <comment_count>2</comment_count>
      <attachid>426410</attachid>
    <who name="Darin Adler">darin</who>
    <bug_when>2021-04-19 14:20:35 -0700</bug_when>
    <thetext>Comment on attachment 426410
Patch

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

Some ideas about better naming and minor code style tweak thoughts.

&gt; Source/WebCore/ChangeLog:11
&gt; +        Replace use of the full CSS parser in CSSFontFaceSet with
&gt; +        CSSPropertyParserWorkerSafe::parseFont to parse font shorthands. This
&gt; +        makes CSSFontFaceSet safe to use in a Worker (required for
&gt; +        OffscreenCanvas) and ought also to be faster.

You describe two obvious advantages here. Are there any disadvantages?

&gt; Source/WebCore/css/CSSFontFaceSet.cpp:311
&gt; +static FontSelectionRequest computeFontSelectionRequest(CSSPropertyParserHelpers::FontRaw&amp; fontRaw)

Why can’t we just name this &quot;font&quot;? Do we really need raw in the variable name? Variable names don}t always have to repeat their type.

&gt; Source/WebCore/css/CSSFontFaceSet.cpp:314
&gt; +        ? WTF::switchOn(*fontRaw.weight, [&amp;] (CSSValueID ident) {

How about a word rather than &quot;ident&quot;? Below I see you using &quot;valueID&quot;. Maybe &quot;keyword&quot; or &quot;identifier&quot;? Or just &quot;weight&quot; would be OK.

&gt; Source/WebCore/css/CSSFontFaceSet.cpp:333
&gt; +    auto stretchSelectionValue = *fontStretchValue(fontRaw.stretch ? *fontRaw.stretch : CSSValueNormal);

Can we use valueOr here instead of ?: in the function.

Glad you wrote a comment explaining why we know this won’t return null; would be even better if we found a way to sidestep that.

&gt; Source/WebCore/css/CSSFontFaceSet.cpp:335
&gt; +    auto valueID = fontRaw.style ? fontRaw.style-&gt;style : CSSValueNormal;

I might name this local variable &quot;style&quot; or &quot;styleKeyword&quot;. Naming it &quot;valueID&quot; seems a bit oblque.

&gt; Source/WebCore/css/CSSFontFaceSet.cpp:344
&gt; +            degrees = static_cast&lt;float&gt;(CSSPrimitiveValue::computeDegrees(fontRaw.style-&gt;angle-&gt;type, fontRaw.style-&gt;angle-&gt;value));

Do we really need to downcast to float? Can we keep it double until we construct the FontSelectionValue? Seems like FontSelectionValue should have a constructor that takes a double as well as the one that takes a float.

&gt; Source/WebCore/css/CSSFontFaceSet.cpp:346
&gt; +        else
&gt; +            degrees = 0;

I think initializing to 0 would be better than using else.

&gt; Source/WebCore/css/CSSFontFaceSet.cpp:372
&gt; +    auto fontRaw = CSSPropertyParserWorkerSafe::parseFont(font, HTMLStandardMode);

Seems to me that the fontRaw deserves the name &quot;font&quot;, and the font string passed in is the thing that should have a different name to make it clear what kind of unparsed font string it is.

I think it’s really strange that we have two strings, one named font and one named string, coming into this function. Very hard to me to understand the purpose of the second string.

&gt; Source/WebCore/css/CSSFontFaceSet.cpp:378
&gt; +    for (auto&amp; item : fontRaw-&gt;family) {

Not thrilled about the name &quot;item&quot; for the family here.

&gt; Source/WebCore/css/CSSFontFaceSet.cpp:381
&gt; +        WTF::switchOn(item, [&amp;] (CSSValueID ident) {

Same comment about &quot;ident&quot; as above. Maybe familyKeyword.

&gt; Source/WebCore/css/CSSFontFaceSet.cpp:382
&gt; +            isGenericFamily = ident != CSSValueWebkitBody;

Since isGenericFamily is initialized to false above, I suggest we put this expression inside the if and just set isGenericFamily to true in the one case.

&gt; Source/WebCore/css/CSSFontFaceSet.cpp:387
&gt; +                family = AtomString(m_owningFontSelector-&gt;scriptExecutionContext()-&gt;settingsValues().fontGenericFamilies.standardFontFamily());

Why is the explicit cast to AtomString needed here (and not below for familyString for example).

&gt; Source/WebCore/css/CSSFontFaceSet.cpp:390
&gt; +        }, [&amp;] (const String&amp; familyString) {
&gt; +            family = familyString;

It’s not great to have both family and familyString and the difference between them being so subtle. We can name these things whatever we want, and we should name them to help understand the difference between them. Maybe just rename to familyNonAtomString.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1752176</commentid>
    <comment_count>3</comment_count>
      <attachid>426526</attachid>
    <who name="Chris Lord">clord</who>
    <bug_when>2021-04-20 01:54:53 -0700</bug_when>
    <thetext>Created attachment 426526
Patch</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1752192</commentid>
    <comment_count>4</comment_count>
    <who name="Chris Lord">clord</who>
    <bug_when>2021-04-20 02:30:24 -0700</bug_when>
    <thetext>Most comments addressed in the patch, notes in-line:

(In reply to Darin Adler from comment #2)
&gt; &gt; Source/WebCore/ChangeLog:11
&gt; &gt; +        Replace use of the full CSS parser in CSSFontFaceSet with
&gt; &gt; +        CSSPropertyParserWorkerSafe::parseFont to parse font shorthands. This
&gt; &gt; +        makes CSSFontFaceSet safe to use in a Worker (required for
&gt; &gt; +        OffscreenCanvas) and ought also to be faster.
&gt; 
&gt; You describe two obvious advantages here. Are there any disadvantages?

I added a note to say that it comes at a slight increase in code-length (although really this is only because we can&apos;t use Style::BuilderConverter). I don&apos;t think there are any disadvantages for this use-case, much like with canvas - this path has no need for the parsed CSS values, and that&apos;s the only drawback of using the raw path (that it doesn&apos;t give you CSS values, and generating them from the raw path doesn&apos;t necessarily give you the same result 1:1 as if you used the full parser).

&gt; Glad you wrote a comment explaining why we know this won’t return null;
&gt; would be even better if we found a way to sidestep that.

I replaced the straight dereference with an assert and a later dereference, just in case, and eased up the wording of the comment - if someone changed either of the dependent functions independently, there&apos;s a chance this could fail, so now there&apos;s an assert next to the comment that explains why that happens. Tests should catch if someone ever did that too, these paths are used quite heavily, but better safe than sorry.

&gt; &gt; Source/WebCore/css/CSSFontFaceSet.cpp:344
&gt; &gt; +            degrees = static_cast&lt;float&gt;(CSSPrimitiveValue::computeDegrees(fontRaw.style-&gt;angle-&gt;type, fontRaw.style-&gt;angle-&gt;value));
&gt; 
&gt; Do we really need to downcast to float? Can we keep it double until we
&gt; construct the FontSelectionValue? Seems like FontSelectionValue should have
&gt; a constructor that takes a double as well as the one that takes a float.

FontSelectionValue only has float constructors - I&apos;ve left this as is for now. It&apos;s a 16-bit fixed point value, but I suppose there may be a range of values that double could express that float can&apos;t and may be closer to the nearest fixed point representation? I&apos;ve not thought this through rigorously, but I don&apos;t expect there&apos;s much of a trade-off here and this apes the behaviour before this patch anyway.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1752194</commentid>
    <comment_count>5</comment_count>
    <who name="Chris Lord">clord</who>
    <bug_when>2021-04-20 02:34:43 -0700</bug_when>
    <thetext>(In reply to Chris Lord from comment #4)
&gt; (In reply to Darin Adler from comment #2)
&gt; &gt; Do we really need to downcast to float? Can we keep it double until we
&gt; &gt; construct the FontSelectionValue? Seems like FontSelectionValue should have
&gt; &gt; a constructor that takes a double as well as the one that takes a float.
&gt; 
&gt; FontSelectionValue only has float constructors - I&apos;ve left this as is for
&gt; now. It&apos;s a 16-bit fixed point value, but I suppose there may be a range of
&gt; values that double could express that float can&apos;t and may be closer to the
&gt; nearest fixed point representation? I&apos;ve not thought this through
&gt; rigorously, but I don&apos;t expect there&apos;s much of a trade-off here and this
&gt; apes the behaviour before this patch anyway.
Oh, I missed this comment somehow from FontSelectionValue:

&gt; // Since floats have 23 mantissa bits, every value can be represented losslessly.
Perhaps it would&apos;ve been nicer to keep the double and cast only when constructing, but this is pretty minor I suppose.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1752200</commentid>
    <comment_count>6</comment_count>
    <who name="EWS">ews-feeder</who>
    <bug_when>2021-04-20 02:50:30 -0700</bug_when>
    <thetext>Committed r276295 (236777@main): &lt;https://commits.webkit.org/236777@main&gt;

All reviewed patches have been landed. Closing bug and clearing flags on attachment 426526.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1752253</commentid>
    <comment_count>7</comment_count>
    <who name="Darin Adler">darin</who>
    <bug_when>2021-04-20 07:49:43 -0700</bug_when>
    <thetext>(In reply to Chris Lord from comment #4)
&gt; generating them from the raw path doesn&apos;t necessarily give you the same
&gt; result 1:1 as if you used the full parser

I’d like to know more about this. If it doesn’t guarantee the same result, what can be different?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1752256</commentid>
    <comment_count>8</comment_count>
      <attachid>426526</attachid>
    <who name="Darin Adler">darin</who>
    <bug_when>2021-04-20 07:51:19 -0700</bug_when>
    <thetext>Comment on attachment 426526
Patch

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

&gt; Source/WebCore/css/CSSFontFaceSet.cpp:379
&gt; +        WTF::switchOn(familyRaw, [&amp;] (CSSValueID ident) {

Loved the names in your final patch. Missed one here, though. This &quot;ident&quot; should be &quot;keyword&quot; or &quot;familyKeyword&quot;.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1752261</commentid>
    <comment_count>9</comment_count>
    <who name="Chris Lord">clord</who>
    <bug_when>2021-04-20 08:03:34 -0700</bug_when>
    <thetext>(In reply to Darin Adler from comment #7)
&gt; (In reply to Chris Lord from comment #4)
&gt; &gt; generating them from the raw path doesn&apos;t necessarily give you the same
&gt; &gt; result 1:1 as if you used the full parser
&gt; 
&gt; I’d like to know more about this. If it doesn’t guarantee the same result,
&gt; what can be different?

For example, if you use CSS calc, going through this path would not allow you to reconstruct a calc string because it just gets resolved, it doesn&apos;t keep the data necessary to reconstruct the full expression (which using the full parser would). Similarly, if &quot;SANS 10px&quot; was equivalent to &quot;sans 10px&quot;, using the full parser would let you retrieve the exact expression, where as if you reconstructed it using data from FontRaw, likelihood is you&apos;d end up with only the final resolved value and not the valid original input if it differs.

Another example, I had another implementation of the patch in bug 224426 that used the raw parsers instead of making the CSSValue-producing consume functions worker-safe which worked in principle, but failed tests because they (correctly) expect to be able to read back the style string in certain cases. (This should have been obvious, I got ahead of myself and didn&apos;t realise that style strings were read back in that case until I was half-way through)

As we don&apos;t need to read back any style properties from FontFaceSet, we&apos;re ok to use the raw parser. I feel ok without adding a clarifying comment about this in this patch as if we did need to do that in the future (I&apos;m not sure how or why it could change in this particular case, but for the sake of argument), FontRaw doesn&apos;t have any methods that you could use that would get you an almost-correct result, it&apos;d be reasonably obvious that you&apos;d need to use the full parser to do so.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1752263</commentid>
    <comment_count>10</comment_count>
    <who name="Chris Lord">clord</who>
    <bug_when>2021-04-20 08:04:40 -0700</bug_when>
    <thetext>(In reply to Darin Adler from comment #8)
&gt; Comment on attachment 426526 [details]
&gt; Patch
&gt; 
&gt; View in context:
&gt; https://bugs.webkit.org/attachment.cgi?id=426526&amp;action=review
&gt; 
&gt; &gt; Source/WebCore/css/CSSFontFaceSet.cpp:379
&gt; &gt; +        WTF::switchOn(familyRaw, [&amp;] (CSSValueID ident) {
&gt; 
&gt; Loved the names in your final patch. Missed one here, though. This &quot;ident&quot;
&gt; should be &quot;keyword&quot; or &quot;familyKeyword&quot;.

doh! I&apos;ll fix this in a related patch given how small an issue it is.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1752264</commentid>
    <comment_count>11</comment_count>
    <who name="Darin Adler">darin</who>
    <bug_when>2021-04-20 08:07:38 -0700</bug_when>
    <thetext>(In reply to Chris Lord from comment #9)
&gt; For example, if you use CSS calc, going through this path would not allow
&gt; you to reconstruct a calc string because it just gets resolved, it doesn&apos;t
&gt; keep the data necessary to reconstruct the full expression (which using the
&gt; full parser would).

I don’t want us to add a ton of huge comments. But I do want this kind of thing to be immediately obvious when reading the code. I’ll think about what to do.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1753531</commentid>
    <comment_count>12</comment_count>
    <who name="Ling Ho">lingcherd_ho</who>
    <bug_when>2021-04-23 02:54:08 -0700</bug_when>
    <thetext>rdar://76889623</thetext>
  </long_desc>
      
          <attachment
              isobsolete="1"
              ispatch="1"
              isprivate="0"
          >
            <attachid>426410</attachid>
            <date>2021-04-19 05:44:44 -0700</date>
            <delta_ts>2021-04-20 01:54:48 -0700</delta_ts>
            <desc>Patch</desc>
            <filename>bug-224749-20210419134442.patch</filename>
            <type>text/plain</type>
            <size>7570</size>
            <attacher name="Chris Lord">clord</attacher>
            
              <data encoding="base64">U3VidmVyc2lvbiBSZXZpc2lvbjogMjc2MTI5CmRpZmYgLS1naXQgYS9Tb3VyY2UvV2ViQ29yZS9D
aGFuZ2VMb2cgYi9Tb3VyY2UvV2ViQ29yZS9DaGFuZ2VMb2cKaW5kZXggNjYyZTJhZGM5N2Y1ZDY2
OTA2YjA3Mzg3ZGE3NGM2YmE4MTRmOWQxZS4uOGFmNmVmOTQyNGM3ZjlhZDJiOWQ2YzJmYjViYjll
ZGExNmUyZDQ2YyAxMDA2NDQKLS0tIGEvU291cmNlL1dlYkNvcmUvQ2hhbmdlTG9nCisrKyBiL1Nv
dXJjZS9XZWJDb3JlL0NoYW5nZUxvZwpAQCAtMSwzICsxLDIxIEBACisyMDIxLTA0LTE5ICBDaHJp
cyBMb3JkICA8Y2xvcmRAaWdhbGlhLmNvbT4KKworICAgICAgICBEb24ndCB1c2UgdGhlIGZ1bGwg
Q1NTIHBhcnNlciBmb3IgQ1NTRm9udEZhY2VTZXQKKyAgICAgICAgaHR0cHM6Ly9idWdzLndlYmtp
dC5vcmcvc2hvd19idWcuY2dpP2lkPTIyNDc0OQorCisgICAgICAgIFJldmlld2VkIGJ5IE5PQk9E
WSAoT09QUyEpLgorCisgICAgICAgIFJlcGxhY2UgdXNlIG9mIHRoZSBmdWxsIENTUyBwYXJzZXIg
aW4gQ1NTRm9udEZhY2VTZXQgd2l0aAorICAgICAgICBDU1NQcm9wZXJ0eVBhcnNlcldvcmtlclNh
ZmU6OnBhcnNlRm9udCB0byBwYXJzZSBmb250IHNob3J0aGFuZHMuIFRoaXMKKyAgICAgICAgbWFr
ZXMgQ1NTRm9udEZhY2VTZXQgc2FmZSB0byB1c2UgaW4gYSBXb3JrZXIgKHJlcXVpcmVkIGZvcgor
ICAgICAgICBPZmZzY3JlZW5DYW52YXMpIGFuZCBvdWdodCBhbHNvIHRvIGJlIGZhc3Rlci4KKwor
ICAgICAgICBObyBuZXcgdGVzdHMsIGNvdmVyZWQgYnkgZXhpc3RpbmcgdGVzdHMuCisKKyAgICAg
ICAgKiBjc3MvQ1NTRm9udEZhY2VTZXQuY3BwOgorICAgICAgICAoV2ViQ29yZTo6Y29tcHV0ZUZv
bnRTZWxlY3Rpb25SZXF1ZXN0KToKKyAgICAgICAgKFdlYkNvcmU6OkNTU0ZvbnRGYWNlU2V0Ojpt
YXRjaGluZ0ZhY2VzRXhjbHVkaW5nUHJlaW5zdGFsbGVkRm9udHMpOgorCiAyMDIxLTA0LTE2ICBD
aHJpcyBMb3JkICA8Y2xvcmRAaWdhbGlhLmNvbT4KIAogICAgICAgICBJbXBsZW1lbnQgRm9udEZh
Y2UgaW4gV29ya2VycyBmb3IgT2Zmc2NyZWVuQ2FudmFzCmRpZmYgLS1naXQgYS9Tb3VyY2UvV2Vi
Q29yZS9jc3MvQ1NTRm9udEZhY2VTZXQuY3BwIGIvU291cmNlL1dlYkNvcmUvY3NzL0NTU0ZvbnRG
YWNlU2V0LmNwcAppbmRleCAyNjEwYjhiZTBkMTBhYjhjYWFjMzdkODZhNGVjYmQzYzhmNGEzYzMy
Li42Y2Q4Mzc5ZmExOTM3ZGQwMDc0ZjFlMzc1YzEwNzRkNWMwZjY0NDA1IDEwMDY0NAotLS0gYS9T
b3VyY2UvV2ViQ29yZS9jc3MvQ1NTRm9udEZhY2VTZXQuY3BwCisrKyBiL1NvdXJjZS9XZWJDb3Jl
L2Nzcy9DU1NGb250RmFjZVNldC5jcHAKQEAgLTMyLDYgKzMyLDggQEAKICNpbmNsdWRlICJDU1NG
b250U3R5bGVWYWx1ZS5oIgogI2luY2x1ZGUgIkNTU1BhcnNlci5oIgogI2luY2x1ZGUgIkNTU1By
aW1pdGl2ZVZhbHVlLmgiCisjaW5jbHVkZSAiQ1NTUHJvcGVydHlQYXJzZXJIZWxwZXJzLmgiCisj
aW5jbHVkZSAiQ1NTUHJvcGVydHlQYXJzZXJXb3JrZXJTYWZlLmgiCiAjaW5jbHVkZSAiQ1NTU2Vn
bWVudGVkRm9udEZhY2UuaCIKICNpbmNsdWRlICJDU1NWYWx1ZUxpc3QuaCIKICNpbmNsdWRlICJD
U1NWYWx1ZVBvb2wuaCIKQEAgLTMwNiwyOCArMzA4LDQ2IEBAIENTU0ZvbnRGYWNlJiBDU1NGb250
RmFjZVNldDo6b3BlcmF0b3JbXShzaXplX3QgaSkKICAgICByZXR1cm4gbV9mYWNlc1tpXTsKIH0K
IAotc3RhdGljIEV4Y2VwdGlvbk9yPEZvbnRTZWxlY3Rpb25SZXF1ZXN0PiBjb21wdXRlRm9udFNl
bGVjdGlvblJlcXVlc3QoTXV0YWJsZVN0eWxlUHJvcGVydGllcyYgc3R5bGUpCitzdGF0aWMgRm9u
dFNlbGVjdGlvblJlcXVlc3QgY29tcHV0ZUZvbnRTZWxlY3Rpb25SZXF1ZXN0KENTU1Byb3BlcnR5
UGFyc2VySGVscGVyczo6Rm9udFJhdyYgZm9udFJhdykKIHsKLSAgICBSZWZQdHI8Q1NTVmFsdWU+
IHdlaWdodFZhbHVlID0gc3R5bGUuZ2V0UHJvcGVydHlDU1NWYWx1ZShDU1NQcm9wZXJ0eUZvbnRX
ZWlnaHQpLmdldCgpOwotICAgIGlmICghd2VpZ2h0VmFsdWUgfHwgd2VpZ2h0VmFsdWUtPmlzSW5p
dGlhbFZhbHVlKCkpCi0gICAgICAgIHdlaWdodFZhbHVlID0gQ1NTVmFsdWVQb29sOjpzaW5nbGV0
b24oKS5jcmVhdGVJZGVudGlmaWVyVmFsdWUoQ1NTVmFsdWVOb3JtYWwpLnB0cigpOwotCi0gICAg
UmVmUHRyPENTU1ZhbHVlPiBzdHJldGNoVmFsdWUgPSBzdHlsZS5nZXRQcm9wZXJ0eUNTU1ZhbHVl
KENTU1Byb3BlcnR5Rm9udFN0cmV0Y2gpLmdldCgpOwotICAgIGlmICghc3RyZXRjaFZhbHVlIHx8
IHN0cmV0Y2hWYWx1ZS0+aXNJbml0aWFsVmFsdWUoKSkKLSAgICAgICAgc3RyZXRjaFZhbHVlID0g
Q1NTVmFsdWVQb29sOjpzaW5nbGV0b24oKS5jcmVhdGVJZGVudGlmaWVyVmFsdWUoQ1NTVmFsdWVO
b3JtYWwpLnB0cigpOwotCi0gICAgUmVmUHRyPENTU1ZhbHVlPiBzdHlsZVZhbHVlID0gc3R5bGUu
Z2V0UHJvcGVydHlDU1NWYWx1ZShDU1NQcm9wZXJ0eUZvbnRTdHlsZSkuZ2V0KCk7Ci0gICAgaWYg
KCFzdHlsZVZhbHVlIHx8IHN0eWxlVmFsdWUtPmlzSW5pdGlhbFZhbHVlKCkpCi0gICAgICAgIHN0
eWxlVmFsdWUgPSBDU1NGb250U3R5bGVWYWx1ZTo6Y3JlYXRlKENTU1ZhbHVlUG9vbDo6c2luZ2xl
dG9uKCkuY3JlYXRlSWRlbnRpZmllclZhbHVlKENTU1ZhbHVlTm9ybWFsKSk7Ci0KLSAgICBpZiAo
d2VpZ2h0VmFsdWUtPmlzR2xvYmFsS2V5d29yZCgpIHx8IHN0cmV0Y2hWYWx1ZS0+aXNHbG9iYWxL
ZXl3b3JkKCkgfHwgc3R5bGVWYWx1ZS0+aXNHbG9iYWxLZXl3b3JkKCkpCi0gICAgICAgIHJldHVy
biBFeGNlcHRpb24geyBTeW50YXhFcnJvciB9OwotCi0gICAgYXV0byB3ZWlnaHRTZWxlY3Rpb25W
YWx1ZSA9IFN0eWxlOjpCdWlsZGVyQ29udmVydGVyOjpjb252ZXJ0Rm9udFdlaWdodEZyb21WYWx1
ZSgqd2VpZ2h0VmFsdWUpOwotICAgIGF1dG8gc3RyZXRjaFNlbGVjdGlvblZhbHVlID0gU3R5bGU6
OkJ1aWxkZXJDb252ZXJ0ZXI6OmNvbnZlcnRGb250U3RyZXRjaEZyb21WYWx1ZSgqc3RyZXRjaFZh
bHVlKTsKLSAgICBhdXRvIHN0eWxlU2VsZWN0aW9uVmFsdWUgPSBTdHlsZTo6QnVpbGRlckNvbnZl
cnRlcjo6Y29udmVydEZvbnRTdHlsZUZyb21WYWx1ZSgqc3R5bGVWYWx1ZSk7CisgICAgYXV0byB3
ZWlnaHRTZWxlY3Rpb25WYWx1ZSA9IGZvbnRSYXcud2VpZ2h0CisgICAgICAgID8gV1RGOjpzd2l0
Y2hPbigqZm9udFJhdy53ZWlnaHQsIFsmXSAoQ1NTVmFsdWVJRCBpZGVudCkgeworICAgICAgICAg
ICAgc3dpdGNoIChpZGVudCkgeworICAgICAgICAgICAgY2FzZSBDU1NWYWx1ZU5vcm1hbDoKKyAg
ICAgICAgICAgICAgICByZXR1cm4gbm9ybWFsV2VpZ2h0VmFsdWUoKTsKKyAgICAgICAgICAgIGNh
c2UgQ1NTVmFsdWVCb2xkOgorICAgICAgICAgICAgY2FzZSBDU1NWYWx1ZUJvbGRlcjoKKyAgICAg
ICAgICAgICAgICByZXR1cm4gYm9sZFdlaWdodFZhbHVlKCk7CisgICAgICAgICAgICBjYXNlIENT
U1ZhbHVlTGlnaHRlcjoKKyAgICAgICAgICAgICAgICByZXR1cm4gbGlnaHRXZWlnaHRWYWx1ZSgp
OworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICBBU1NFUlRfTk9UX1JFQUNI
RUQoKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gbm9ybWFsV2VpZ2h0VmFsdWUoKTsKKyAgICAg
ICAgICAgIH0KKyAgICAgICAgfSwgWyZdIChkb3VibGUgd2VpZ2h0KSB7CisgICAgICAgICAgICBy
ZXR1cm4gRm9udFNlbGVjdGlvblZhbHVlOjpjbGFtcEZsb2F0KHdlaWdodCk7CisgICAgICAgIH0p
IDogbm9ybWFsV2VpZ2h0VmFsdWUoKTsKKworICAgIC8vIEJlY2F1c2UgdGhpcyBpcyBhIEZvbnRS
YXcsIHdlIGtub3cgd2UgY2FuIGRlcmVmZXJlbmNlIHRoZSByZXR1cm4gZnJvbSBmb250U3RyZXRj
aFZhbHVlIGFzCisgICAgLy8gY29uc3VtZUZvbnRTdHJldGNoS2V5d29yZFZhbHVlUmF3IG9ubHkg
cmV0dXJucyByZXN1bHRzIHZhbGlkIHRvIHBhc3MgdG8gZm9udFN0cmV0Y2hWYWx1ZS4KKyAgICBh
dXRvIHN0cmV0Y2hTZWxlY3Rpb25WYWx1ZSA9ICpmb250U3RyZXRjaFZhbHVlKGZvbnRSYXcuc3Ry
ZXRjaCA/ICpmb250UmF3LnN0cmV0Y2ggOiBDU1NWYWx1ZU5vcm1hbCk7CisKKyAgICBhdXRvIHZh
bHVlSUQgPSBmb250UmF3LnN0eWxlID8gZm9udFJhdy5zdHlsZS0+c3R5bGUgOiBDU1NWYWx1ZU5v
cm1hbDsKKyAgICBhdXRvIHN0eWxlU2VsZWN0aW9uVmFsdWUgPSBbJl0gKCkgLT4gT3B0aW9uYWw8
Rm9udFNlbGVjdGlvblZhbHVlPiB7CisgICAgICAgIGlmICh2YWx1ZUlEID09IENTU1ZhbHVlTm9y
bWFsKQorICAgICAgICAgICAgcmV0dXJuIFdURjo6bnVsbG9wdDsKKyAgICAgICAgaWYgKHZhbHVl
SUQgPT0gQ1NTVmFsdWVJdGFsaWMpCisgICAgICAgICAgICByZXR1cm4gaXRhbGljVmFsdWUoKTsK
KyAgICAgICAgQVNTRVJUKGZvbnRSYXcuc3R5bGUgJiYgdmFsdWVJRCA9PSBDU1NWYWx1ZU9ibGlx
dWUpOworICAgICAgICBmbG9hdCBkZWdyZWVzOworICAgICAgICBpZiAoZm9udFJhdy5zdHlsZS0+
YW5nbGUpCisgICAgICAgICAgICBkZWdyZWVzID0gc3RhdGljX2Nhc3Q8ZmxvYXQ+KENTU1ByaW1p
dGl2ZVZhbHVlOjpjb21wdXRlRGVncmVlcyhmb250UmF3LnN0eWxlLT5hbmdsZS0+dHlwZSwgZm9u
dFJhdy5zdHlsZS0+YW5nbGUtPnZhbHVlKSk7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIGRl
Z3JlZXMgPSAwOworICAgICAgICByZXR1cm4gRm9udFNlbGVjdGlvblZhbHVlKGRlZ3JlZXMpOwor
ICAgIH0oKTsKIAotICAgIHJldHVybiB7eyB3ZWlnaHRTZWxlY3Rpb25WYWx1ZSwgc3RyZXRjaFNl
bGVjdGlvblZhbHVlLCBzdHlsZVNlbGVjdGlvblZhbHVlIH19OworICAgIHJldHVybiB7IHdlaWdo
dFNlbGVjdGlvblZhbHVlLCBzdHJldGNoU2VsZWN0aW9uVmFsdWUsIHN0eWxlU2VsZWN0aW9uVmFs
dWUgfTsKIH0KIAogdXNpbmcgQ29kZVBvaW50c01hcCA9IEhhc2hTZXQ8VUNoYXIzMiwgRGVmYXVs
dEhhc2g8VUNoYXIzMj4sIFdURjo6VW5zaWduZWRXaXRoWmVyb0tleUhhc2hUcmFpdHM8VUNoYXIz
Mj4+OwpAQCAtMzQ5LDMyICszNjksMzMgQEAgc3RhdGljIENvZGVQb2ludHNNYXAgY29kZVBvaW50
c0Zyb21TdHJpbmcoU3RyaW5nVmlldyBzdHJpbmdWaWV3KQogCiBFeGNlcHRpb25PcjxWZWN0b3I8
c3RkOjpyZWZlcmVuY2Vfd3JhcHBlcjxDU1NGb250RmFjZT4+PiBDU1NGb250RmFjZVNldDo6bWF0
Y2hpbmdGYWNlc0V4Y2x1ZGluZ1ByZWluc3RhbGxlZEZvbnRzKGNvbnN0IFN0cmluZyYgZm9udCwg
Y29uc3QgU3RyaW5nJiBzdHJpbmcpCiB7Ci0gICAgYXV0byBzdHlsZSA9IE11dGFibGVTdHlsZVBy
b3BlcnRpZXM6OmNyZWF0ZSgpOwotICAgIGF1dG8gcGFyc2VSZXN1bHQgPSBDU1NQYXJzZXI6OnBh
cnNlVmFsdWUoc3R5bGUsIENTU1Byb3BlcnR5Rm9udCwgZm9udCwgdHJ1ZSwgSFRNTFN0YW5kYXJk
TW9kZSk7Ci0gICAgaWYgKHBhcnNlUmVzdWx0ID09IENTU1BhcnNlcjo6UGFyc2VSZXN1bHQ6OkVy
cm9yKQorICAgIGF1dG8gZm9udFJhdyA9IENTU1Byb3BlcnR5UGFyc2VyV29ya2VyU2FmZTo6cGFy
c2VGb250KGZvbnQsIEhUTUxTdGFuZGFyZE1vZGUpOworICAgIGlmICghZm9udFJhdykKICAgICAg
ICAgcmV0dXJuIEV4Y2VwdGlvbiB7IFN5bnRheEVycm9yIH07CiAKLSAgICBhdXRvIHJlcXVlc3RP
ckV4Y2VwdGlvbiA9IGNvbXB1dGVGb250U2VsZWN0aW9uUmVxdWVzdChzdHlsZS5nZXQoKSk7Ci0g
ICAgaWYgKHJlcXVlc3RPckV4Y2VwdGlvbi5oYXNFeGNlcHRpb24oKSkKLSAgICAgICAgcmV0dXJu
IHJlcXVlc3RPckV4Y2VwdGlvbi5yZWxlYXNlRXhjZXB0aW9uKCk7Ci0gICAgYXV0byByZXF1ZXN0
ID0gcmVxdWVzdE9yRXhjZXB0aW9uLnJlbGVhc2VSZXR1cm5WYWx1ZSgpOwotCi0gICAgYXV0byBm
YW1pbHkgPSBzdHlsZS0+Z2V0UHJvcGVydHlDU1NWYWx1ZShDU1NQcm9wZXJ0eUZvbnRGYW1pbHkp
OwotICAgIGlmICghaXM8Q1NTVmFsdWVMaXN0PihmYW1pbHkpKQotICAgICAgICByZXR1cm4gRXhj
ZXB0aW9uIHsgU3ludGF4RXJyb3IgfTsKLSAgICBDU1NWYWx1ZUxpc3QmIGZhbWlseUxpc3QgPSBk
b3duY2FzdDxDU1NWYWx1ZUxpc3Q+KCpmYW1pbHkpOwotCiAgICAgSGFzaFNldDxBdG9tU3RyaW5n
PiB1bmlxdWVGYW1pbGllczsKICAgICBWZWN0b3I8QXRvbVN0cmluZz4gZmFtaWx5T3JkZXI7Ci0g
ICAgZm9yIChhdXRvJiBmYW1pbHkgOiBmYW1pbHlMaXN0KSB7Ci0gICAgICAgIGF1dG8mIHByaW1p
dGl2ZSA9IGRvd25jYXN0PENTU1ByaW1pdGl2ZVZhbHVlPihmYW1pbHkuZ2V0KCkpOwotICAgICAg
ICBpZiAoIXByaW1pdGl2ZS5pc0ZvbnRGYW1pbHkoKSkKLSAgICAgICAgICAgIGNvbnRpbnVlOwot
ICAgICAgICBpZiAodW5pcXVlRmFtaWxpZXMuYWRkKHByaW1pdGl2ZS5mb250RmFtaWx5KCkuZmFt
aWx5TmFtZSkuaXNOZXdFbnRyeSkKLSAgICAgICAgICAgIGZhbWlseU9yZGVyLmFwcGVuZChwcmlt
aXRpdmUuZm9udEZhbWlseSgpLmZhbWlseU5hbWUpOworICAgIGZvciAoYXV0byYgaXRlbSA6IGZv
bnRSYXctPmZhbWlseSkgeworICAgICAgICBBdG9tU3RyaW5nIGZhbWlseTsKKyAgICAgICAgYm9v
bCBpc0dlbmVyaWNGYW1pbHkgPSBmYWxzZTsKKyAgICAgICAgV1RGOjpzd2l0Y2hPbihpdGVtLCBb
Jl0gKENTU1ZhbHVlSUQgaWRlbnQpIHsKKyAgICAgICAgICAgIGlzR2VuZXJpY0ZhbWlseSA9IGlk
ZW50ICE9IENTU1ZhbHVlV2Via2l0Qm9keTsKKyAgICAgICAgICAgIGlmIChpc0dlbmVyaWNGYW1p
bHkpCisgICAgICAgICAgICAgICAgZmFtaWx5ID0gZmFtaWx5TmFtZXNEYXRhLT5hdChDU1NQcm9w
ZXJ0eVBhcnNlckhlbHBlcnM6OmdlbmVyaWNGb250RmFtaWx5SW5kZXgoaWRlbnQpKTsKKyAgICAg
ICAgICAgIGVsc2UgeworICAgICAgICAgICAgICAgIEFTU0VSVChtX293bmluZ0ZvbnRTZWxlY3Rv
ciAmJiBtX293bmluZ0ZvbnRTZWxlY3Rvci0+c2NyaXB0RXhlY3V0aW9uQ29udGV4dCgpKTsKKyAg
ICAgICAgICAgICAgICBmYW1pbHkgPSBBdG9tU3RyaW5nKG1fb3duaW5nRm9udFNlbGVjdG9yLT5z
Y3JpcHRFeGVjdXRpb25Db250ZXh0KCktPnNldHRpbmdzVmFsdWVzKCkuZm9udEdlbmVyaWNGYW1p
bGllcy5zdGFuZGFyZEZvbnRGYW1pbHkoKSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0sIFsm
XSAoY29uc3QgU3RyaW5nJiBmYW1pbHlTdHJpbmcpIHsKKyAgICAgICAgICAgIGZhbWlseSA9IGZh
bWlseVN0cmluZzsKKyAgICAgICAgfSk7CisKKyAgICAgICAgaWYgKCFmYW1pbHkuaXNFbXB0eSgp
ICYmIHVuaXF1ZUZhbWlsaWVzLmFkZChmYW1pbHkpLmlzTmV3RW50cnkpCisgICAgICAgICAgICBm
YW1pbHlPcmRlci5hcHBlbmQoZmFtaWx5KTsKICAgICB9CiAKICAgICBIYXNoU2V0PENTU0ZvbnRG
YWNlKj4gcmVzdWx0Q29uc3RpdHVlbnRzOworICAgIGF1dG8gcmVxdWVzdCA9IGNvbXB1dGVGb250
U2VsZWN0aW9uUmVxdWVzdCgqZm9udFJhdyk7CiAgICAgZm9yIChhdXRvIGNvZGVQb2ludCA6IGNv
ZGVQb2ludHNGcm9tU3RyaW5nKHN0cmluZykpIHsKICAgICAgICAgYm9vbCBmb3VuZCA9IGZhbHNl
OwogICAgICAgICBmb3IgKGF1dG8mIGZhbWlseSA6IGZhbWlseU9yZGVyKSB7Cg==
</data>

          </attachment>
          <attachment
              isobsolete="0"
              ispatch="1"
              isprivate="0"
          >
            <attachid>426526</attachid>
            <date>2021-04-20 01:54:53 -0700</date>
            <delta_ts>2021-04-20 02:50:32 -0700</delta_ts>
            <desc>Patch</desc>
            <filename>bug-224749-20210420095451.patch</filename>
            <type>text/plain</type>
            <size>7738</size>
            <attacher name="Chris Lord">clord</attacher>
            
              <data encoding="base64">U3VidmVyc2lvbiBSZXZpc2lvbjogMjc2MTI5CmRpZmYgLS1naXQgYS9Tb3VyY2UvV2ViQ29yZS9D
aGFuZ2VMb2cgYi9Tb3VyY2UvV2ViQ29yZS9DaGFuZ2VMb2cKaW5kZXggNjYyZTJhZGM5N2Y1ZDY2
OTA2YjA3Mzg3ZGE3NGM2YmE4MTRmOWQxZS4uMzVkZTIxMGYxZDY5OGQ1OTMxYjdmM2I5NWQzZTc3
YjkyNzI2ZjRhNSAxMDA2NDQKLS0tIGEvU291cmNlL1dlYkNvcmUvQ2hhbmdlTG9nCisrKyBiL1Nv
dXJjZS9XZWJDb3JlL0NoYW5nZUxvZwpAQCAtMSwzICsxLDIyIEBACisyMDIxLTA0LTE5ICBDaHJp
cyBMb3JkICA8Y2xvcmRAaWdhbGlhLmNvbT4KKworICAgICAgICBEb24ndCB1c2UgdGhlIGZ1bGwg
Q1NTIHBhcnNlciBmb3IgQ1NTRm9udEZhY2VTZXQKKyAgICAgICAgaHR0cHM6Ly9idWdzLndlYmtp
dC5vcmcvc2hvd19idWcuY2dpP2lkPTIyNDc0OQorCisgICAgICAgIFJldmlld2VkIGJ5IERhcmlu
IEFkbGVyLgorCisgICAgICAgIFJlcGxhY2UgdXNlIG9mIHRoZSBmdWxsIENTUyBwYXJzZXIgaW4g
Q1NTRm9udEZhY2VTZXQgd2l0aAorICAgICAgICBDU1NQcm9wZXJ0eVBhcnNlcldvcmtlclNhZmU6
OnBhcnNlRm9udCB0byBwYXJzZSBmb250IHNob3J0aGFuZHMuIFRoaXMKKyAgICAgICAgbWFrZXMg
Q1NTRm9udEZhY2VTZXQgc2FmZSB0byB1c2UgaW4gYSBXb3JrZXIgKHJlcXVpcmVkIGZvcgorICAg
ICAgICBPZmZzY3JlZW5DYW52YXMpIGFuZCBvdWdodCBhbHNvIHRvIGJlIGZhc3RlciwgYXQgdGhl
IGNvc3Qgb2YgYSBzbGlnaHQKKyAgICAgICAgaW5jcmVhc2UgaW4gbGluZXMgb2YgY29kZS4KKwor
ICAgICAgICBObyBuZXcgdGVzdHMsIGNvdmVyZWQgYnkgZXhpc3RpbmcgdGVzdHMuCisKKyAgICAg
ICAgKiBjc3MvQ1NTRm9udEZhY2VTZXQuY3BwOgorICAgICAgICAoV2ViQ29yZTo6Y29tcHV0ZUZv
bnRTZWxlY3Rpb25SZXF1ZXN0KToKKyAgICAgICAgKFdlYkNvcmU6OkNTU0ZvbnRGYWNlU2V0Ojpt
YXRjaGluZ0ZhY2VzRXhjbHVkaW5nUHJlaW5zdGFsbGVkRm9udHMpOgorCiAyMDIxLTA0LTE2ICBD
aHJpcyBMb3JkICA8Y2xvcmRAaWdhbGlhLmNvbT4KIAogICAgICAgICBJbXBsZW1lbnQgRm9udEZh
Y2UgaW4gV29ya2VycyBmb3IgT2Zmc2NyZWVuQ2FudmFzCmRpZmYgLS1naXQgYS9Tb3VyY2UvV2Vi
Q29yZS9jc3MvQ1NTRm9udEZhY2VTZXQuY3BwIGIvU291cmNlL1dlYkNvcmUvY3NzL0NTU0ZvbnRG
YWNlU2V0LmNwcAppbmRleCAyNjEwYjhiZTBkMTBhYjhjYWFjMzdkODZhNGVjYmQzYzhmNGEzYzMy
Li4xNGZjZWU2Mzg3NGQ2ZDNhN2IxNDA0NThiY2VlOWZlMzBjZGVkMzVhIDEwMDY0NAotLS0gYS9T
b3VyY2UvV2ViQ29yZS9jc3MvQ1NTRm9udEZhY2VTZXQuY3BwCisrKyBiL1NvdXJjZS9XZWJDb3Jl
L2Nzcy9DU1NGb250RmFjZVNldC5jcHAKQEAgLTMyLDYgKzMyLDggQEAKICNpbmNsdWRlICJDU1NG
b250U3R5bGVWYWx1ZS5oIgogI2luY2x1ZGUgIkNTU1BhcnNlci5oIgogI2luY2x1ZGUgIkNTU1By
aW1pdGl2ZVZhbHVlLmgiCisjaW5jbHVkZSAiQ1NTUHJvcGVydHlQYXJzZXJIZWxwZXJzLmgiCisj
aW5jbHVkZSAiQ1NTUHJvcGVydHlQYXJzZXJXb3JrZXJTYWZlLmgiCiAjaW5jbHVkZSAiQ1NTU2Vn
bWVudGVkRm9udEZhY2UuaCIKICNpbmNsdWRlICJDU1NWYWx1ZUxpc3QuaCIKICNpbmNsdWRlICJD
U1NWYWx1ZVBvb2wuaCIKQEAgLTMwNiwyOCArMzA4LDQ1IEBAIENTU0ZvbnRGYWNlJiBDU1NGb250
RmFjZVNldDo6b3BlcmF0b3JbXShzaXplX3QgaSkKICAgICByZXR1cm4gbV9mYWNlc1tpXTsKIH0K
IAotc3RhdGljIEV4Y2VwdGlvbk9yPEZvbnRTZWxlY3Rpb25SZXF1ZXN0PiBjb21wdXRlRm9udFNl
bGVjdGlvblJlcXVlc3QoTXV0YWJsZVN0eWxlUHJvcGVydGllcyYgc3R5bGUpCitzdGF0aWMgRm9u
dFNlbGVjdGlvblJlcXVlc3QgY29tcHV0ZUZvbnRTZWxlY3Rpb25SZXF1ZXN0KENTU1Byb3BlcnR5
UGFyc2VySGVscGVyczo6Rm9udFJhdyYgZm9udCkKIHsKLSAgICBSZWZQdHI8Q1NTVmFsdWU+IHdl
aWdodFZhbHVlID0gc3R5bGUuZ2V0UHJvcGVydHlDU1NWYWx1ZShDU1NQcm9wZXJ0eUZvbnRXZWln
aHQpLmdldCgpOwotICAgIGlmICghd2VpZ2h0VmFsdWUgfHwgd2VpZ2h0VmFsdWUtPmlzSW5pdGlh
bFZhbHVlKCkpCi0gICAgICAgIHdlaWdodFZhbHVlID0gQ1NTVmFsdWVQb29sOjpzaW5nbGV0b24o
KS5jcmVhdGVJZGVudGlmaWVyVmFsdWUoQ1NTVmFsdWVOb3JtYWwpLnB0cigpOwotCi0gICAgUmVm
UHRyPENTU1ZhbHVlPiBzdHJldGNoVmFsdWUgPSBzdHlsZS5nZXRQcm9wZXJ0eUNTU1ZhbHVlKENT
U1Byb3BlcnR5Rm9udFN0cmV0Y2gpLmdldCgpOwotICAgIGlmICghc3RyZXRjaFZhbHVlIHx8IHN0
cmV0Y2hWYWx1ZS0+aXNJbml0aWFsVmFsdWUoKSkKLSAgICAgICAgc3RyZXRjaFZhbHVlID0gQ1NT
VmFsdWVQb29sOjpzaW5nbGV0b24oKS5jcmVhdGVJZGVudGlmaWVyVmFsdWUoQ1NTVmFsdWVOb3Jt
YWwpLnB0cigpOwotCi0gICAgUmVmUHRyPENTU1ZhbHVlPiBzdHlsZVZhbHVlID0gc3R5bGUuZ2V0
UHJvcGVydHlDU1NWYWx1ZShDU1NQcm9wZXJ0eUZvbnRTdHlsZSkuZ2V0KCk7Ci0gICAgaWYgKCFz
dHlsZVZhbHVlIHx8IHN0eWxlVmFsdWUtPmlzSW5pdGlhbFZhbHVlKCkpCi0gICAgICAgIHN0eWxl
VmFsdWUgPSBDU1NGb250U3R5bGVWYWx1ZTo6Y3JlYXRlKENTU1ZhbHVlUG9vbDo6c2luZ2xldG9u
KCkuY3JlYXRlSWRlbnRpZmllclZhbHVlKENTU1ZhbHVlTm9ybWFsKSk7Ci0KLSAgICBpZiAod2Vp
Z2h0VmFsdWUtPmlzR2xvYmFsS2V5d29yZCgpIHx8IHN0cmV0Y2hWYWx1ZS0+aXNHbG9iYWxLZXl3
b3JkKCkgfHwgc3R5bGVWYWx1ZS0+aXNHbG9iYWxLZXl3b3JkKCkpCi0gICAgICAgIHJldHVybiBF
eGNlcHRpb24geyBTeW50YXhFcnJvciB9OwotCi0gICAgYXV0byB3ZWlnaHRTZWxlY3Rpb25WYWx1
ZSA9IFN0eWxlOjpCdWlsZGVyQ29udmVydGVyOjpjb252ZXJ0Rm9udFdlaWdodEZyb21WYWx1ZSgq
d2VpZ2h0VmFsdWUpOwotICAgIGF1dG8gc3RyZXRjaFNlbGVjdGlvblZhbHVlID0gU3R5bGU6OkJ1
aWxkZXJDb252ZXJ0ZXI6OmNvbnZlcnRGb250U3RyZXRjaEZyb21WYWx1ZSgqc3RyZXRjaFZhbHVl
KTsKLSAgICBhdXRvIHN0eWxlU2VsZWN0aW9uVmFsdWUgPSBTdHlsZTo6QnVpbGRlckNvbnZlcnRl
cjo6Y29udmVydEZvbnRTdHlsZUZyb21WYWx1ZSgqc3R5bGVWYWx1ZSk7Ci0KLSAgICByZXR1cm4g
e3sgd2VpZ2h0U2VsZWN0aW9uVmFsdWUsIHN0cmV0Y2hTZWxlY3Rpb25WYWx1ZSwgc3R5bGVTZWxl
Y3Rpb25WYWx1ZSB9fTsKKyAgICBhdXRvIHdlaWdodFNlbGVjdGlvblZhbHVlID0gZm9udC53ZWln
aHQKKyAgICAgICAgPyBXVEY6OnN3aXRjaE9uKCpmb250LndlaWdodCwgWyZdIChDU1NWYWx1ZUlE
IGtleXdvcmQpIHsKKyAgICAgICAgICAgIHN3aXRjaCAoa2V5d29yZCkgeworICAgICAgICAgICAg
Y2FzZSBDU1NWYWx1ZU5vcm1hbDoKKyAgICAgICAgICAgICAgICByZXR1cm4gbm9ybWFsV2VpZ2h0
VmFsdWUoKTsKKyAgICAgICAgICAgIGNhc2UgQ1NTVmFsdWVCb2xkOgorICAgICAgICAgICAgY2Fz
ZSBDU1NWYWx1ZUJvbGRlcjoKKyAgICAgICAgICAgICAgICByZXR1cm4gYm9sZFdlaWdodFZhbHVl
KCk7CisgICAgICAgICAgICBjYXNlIENTU1ZhbHVlTGlnaHRlcjoKKyAgICAgICAgICAgICAgICBy
ZXR1cm4gbGlnaHRXZWlnaHRWYWx1ZSgpOworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAg
ICAgICAgICBBU1NFUlRfTk9UX1JFQUNIRUQoKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gbm9y
bWFsV2VpZ2h0VmFsdWUoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSwgWyZdIChkb3VibGUg
d2VpZ2h0KSB7CisgICAgICAgICAgICByZXR1cm4gRm9udFNlbGVjdGlvblZhbHVlOjpjbGFtcEZs
b2F0KHdlaWdodCk7CisgICAgICAgIH0pIDogbm9ybWFsV2VpZ2h0VmFsdWUoKTsKKworICAgIC8v
IEJlY2F1c2UgdGhpcyBpcyBhIEZvbnRSYXcsIHdlIGtub3cgd2Ugc2hvdWxkIGJlIGFibGUgdG8g
ZGVyZWZlcmVuY2Ugc3RyZXRjaFNlbGVjdGlvblZhbHVlIGFzCisgICAgLy8gY29uc3VtZUZvbnRT
dHJldGNoS2V5d29yZFZhbHVlUmF3IG9ubHkgcmV0dXJucyByZXN1bHRzIHZhbGlkIHRvIHBhc3Mg
dG8gZm9udFN0cmV0Y2hWYWx1ZS4KKyAgICBhdXRvIHN0cmV0Y2hTZWxlY3Rpb25WYWx1ZSA9IGZv
bnRTdHJldGNoVmFsdWUoZm9udC5zdHJldGNoLnZhbHVlT3IoQ1NTVmFsdWVOb3JtYWwpKTsKKyAg
ICBBU1NFUlQoc3RyZXRjaFNlbGVjdGlvblZhbHVlKTsKKworICAgIGF1dG8gc3R5bGVLZXl3b3Jk
ID0gZm9udC5zdHlsZSA/IGZvbnQuc3R5bGUtPnN0eWxlIDogQ1NTVmFsdWVOb3JtYWw7CisgICAg
YXV0byBzdHlsZVNlbGVjdGlvblZhbHVlID0gWyZdICgpIC0+IE9wdGlvbmFsPEZvbnRTZWxlY3Rp
b25WYWx1ZT4geworICAgICAgICBpZiAoc3R5bGVLZXl3b3JkID09IENTU1ZhbHVlTm9ybWFsKQor
ICAgICAgICAgICAgcmV0dXJuIFdURjo6bnVsbG9wdDsKKyAgICAgICAgaWYgKHN0eWxlS2V5d29y
ZCA9PSBDU1NWYWx1ZUl0YWxpYykKKyAgICAgICAgICAgIHJldHVybiBpdGFsaWNWYWx1ZSgpOwor
ICAgICAgICBBU1NFUlQoZm9udC5zdHlsZSAmJiBzdHlsZUtleXdvcmQgPT0gQ1NTVmFsdWVPYmxp
cXVlKTsKKyAgICAgICAgZmxvYXQgZGVncmVlcyA9IDA7CisgICAgICAgIGlmIChmb250LnN0eWxl
LT5hbmdsZSkKKyAgICAgICAgICAgIGRlZ3JlZXMgPSBzdGF0aWNfY2FzdDxmbG9hdD4oQ1NTUHJp
bWl0aXZlVmFsdWU6OmNvbXB1dGVEZWdyZWVzKGZvbnQuc3R5bGUtPmFuZ2xlLT50eXBlLCBmb250
LnN0eWxlLT5hbmdsZS0+dmFsdWUpKTsKKyAgICAgICAgcmV0dXJuIEZvbnRTZWxlY3Rpb25WYWx1
ZShkZWdyZWVzKTsKKyAgICB9KCk7CisKKyAgICByZXR1cm4geyB3ZWlnaHRTZWxlY3Rpb25WYWx1
ZSwgKnN0cmV0Y2hTZWxlY3Rpb25WYWx1ZSwgc3R5bGVTZWxlY3Rpb25WYWx1ZSB9OwogfQogCiB1
c2luZyBDb2RlUG9pbnRzTWFwID0gSGFzaFNldDxVQ2hhcjMyLCBEZWZhdWx0SGFzaDxVQ2hhcjMy
PiwgV1RGOjpVbnNpZ25lZFdpdGhaZXJvS2V5SGFzaFRyYWl0czxVQ2hhcjMyPj47CkBAIC0zNDcs
MzQgKzM2NiwzMyBAQCBzdGF0aWMgQ29kZVBvaW50c01hcCBjb2RlUG9pbnRzRnJvbVN0cmluZyhT
dHJpbmdWaWV3IHN0cmluZ1ZpZXcpCiAgICAgcmV0dXJuIHJlc3VsdDsKIH0KIAotRXhjZXB0aW9u
T3I8VmVjdG9yPHN0ZDo6cmVmZXJlbmNlX3dyYXBwZXI8Q1NTRm9udEZhY2U+Pj4gQ1NTRm9udEZh
Y2VTZXQ6Om1hdGNoaW5nRmFjZXNFeGNsdWRpbmdQcmVpbnN0YWxsZWRGb250cyhjb25zdCBTdHJp
bmcmIGZvbnQsIGNvbnN0IFN0cmluZyYgc3RyaW5nKQorRXhjZXB0aW9uT3I8VmVjdG9yPHN0ZDo6
cmVmZXJlbmNlX3dyYXBwZXI8Q1NTRm9udEZhY2U+Pj4gQ1NTRm9udEZhY2VTZXQ6Om1hdGNoaW5n
RmFjZXNFeGNsdWRpbmdQcmVpbnN0YWxsZWRGb250cyhjb25zdCBTdHJpbmcmIGZvbnRTaG9ydGhh
bmQsIGNvbnN0IFN0cmluZyYgc3RyaW5nKQogewotICAgIGF1dG8gc3R5bGUgPSBNdXRhYmxlU3R5
bGVQcm9wZXJ0aWVzOjpjcmVhdGUoKTsKLSAgICBhdXRvIHBhcnNlUmVzdWx0ID0gQ1NTUGFyc2Vy
OjpwYXJzZVZhbHVlKHN0eWxlLCBDU1NQcm9wZXJ0eUZvbnQsIGZvbnQsIHRydWUsIEhUTUxTdGFu
ZGFyZE1vZGUpOwotICAgIGlmIChwYXJzZVJlc3VsdCA9PSBDU1NQYXJzZXI6OlBhcnNlUmVzdWx0
OjpFcnJvcikKKyAgICBhdXRvIGZvbnQgPSBDU1NQcm9wZXJ0eVBhcnNlcldvcmtlclNhZmU6OnBh
cnNlRm9udChmb250U2hvcnRoYW5kLCBIVE1MU3RhbmRhcmRNb2RlKTsKKyAgICBpZiAoIWZvbnQp
CiAgICAgICAgIHJldHVybiBFeGNlcHRpb24geyBTeW50YXhFcnJvciB9OwogCi0gICAgYXV0byBy
ZXF1ZXN0T3JFeGNlcHRpb24gPSBjb21wdXRlRm9udFNlbGVjdGlvblJlcXVlc3Qoc3R5bGUuZ2V0
KCkpOwotICAgIGlmIChyZXF1ZXN0T3JFeGNlcHRpb24uaGFzRXhjZXB0aW9uKCkpCi0gICAgICAg
IHJldHVybiByZXF1ZXN0T3JFeGNlcHRpb24ucmVsZWFzZUV4Y2VwdGlvbigpOwotICAgIGF1dG8g
cmVxdWVzdCA9IHJlcXVlc3RPckV4Y2VwdGlvbi5yZWxlYXNlUmV0dXJuVmFsdWUoKTsKLQotICAg
IGF1dG8gZmFtaWx5ID0gc3R5bGUtPmdldFByb3BlcnR5Q1NTVmFsdWUoQ1NTUHJvcGVydHlGb250
RmFtaWx5KTsKLSAgICBpZiAoIWlzPENTU1ZhbHVlTGlzdD4oZmFtaWx5KSkKLSAgICAgICAgcmV0
dXJuIEV4Y2VwdGlvbiB7IFN5bnRheEVycm9yIH07Ci0gICAgQ1NTVmFsdWVMaXN0JiBmYW1pbHlM
aXN0ID0gZG93bmNhc3Q8Q1NTVmFsdWVMaXN0PigqZmFtaWx5KTsKLQogICAgIEhhc2hTZXQ8QXRv
bVN0cmluZz4gdW5pcXVlRmFtaWxpZXM7CiAgICAgVmVjdG9yPEF0b21TdHJpbmc+IGZhbWlseU9y
ZGVyOwotICAgIGZvciAoYXV0byYgZmFtaWx5IDogZmFtaWx5TGlzdCkgewotICAgICAgICBhdXRv
JiBwcmltaXRpdmUgPSBkb3duY2FzdDxDU1NQcmltaXRpdmVWYWx1ZT4oZmFtaWx5LmdldCgpKTsK
LSAgICAgICAgaWYgKCFwcmltaXRpdmUuaXNGb250RmFtaWx5KCkpCi0gICAgICAgICAgICBjb250
aW51ZTsKLSAgICAgICAgaWYgKHVuaXF1ZUZhbWlsaWVzLmFkZChwcmltaXRpdmUuZm9udEZhbWls
eSgpLmZhbWlseU5hbWUpLmlzTmV3RW50cnkpCi0gICAgICAgICAgICBmYW1pbHlPcmRlci5hcHBl
bmQocHJpbWl0aXZlLmZvbnRGYW1pbHkoKS5mYW1pbHlOYW1lKTsKKyAgICBmb3IgKGF1dG8mIGZh
bWlseVJhdyA6IGZvbnQtPmZhbWlseSkgeworICAgICAgICBBdG9tU3RyaW5nIGZhbWlseUF0b207
CisgICAgICAgIFdURjo6c3dpdGNoT24oZmFtaWx5UmF3LCBbJl0gKENTU1ZhbHVlSUQgaWRlbnQp
IHsKKyAgICAgICAgICAgIGlmIChpZGVudCAhPSBDU1NWYWx1ZVdlYmtpdEJvZHkpCisgICAgICAg
ICAgICAgICAgZmFtaWx5QXRvbSA9IGZhbWlseU5hbWVzRGF0YS0+YXQoQ1NTUHJvcGVydHlQYXJz
ZXJIZWxwZXJzOjpnZW5lcmljRm9udEZhbWlseUluZGV4KGlkZW50KSk7CisgICAgICAgICAgICBl
bHNlIHsKKyAgICAgICAgICAgICAgICBBU1NFUlQobV9vd25pbmdGb250U2VsZWN0b3IgJiYgbV9v
d25pbmdGb250U2VsZWN0b3ItPnNjcmlwdEV4ZWN1dGlvbkNvbnRleHQoKSk7CisgICAgICAgICAg
ICAgICAgZmFtaWx5QXRvbSA9IG1fb3duaW5nRm9udFNlbGVjdG9yLT5zY3JpcHRFeGVjdXRpb25D
b250ZXh0KCktPnNldHRpbmdzVmFsdWVzKCkuZm9udEdlbmVyaWNGYW1pbGllcy5zdGFuZGFyZEZv
bnRGYW1pbHkoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSwgWyZdIChjb25zdCBTdHJpbmcm
IGZhbWlseVN0cmluZykgeworICAgICAgICAgICAgZmFtaWx5QXRvbSA9IGZhbWlseVN0cmluZzsK
KyAgICAgICAgfSk7CisKKyAgICAgICAgaWYgKCFmYW1pbHlBdG9tLmlzRW1wdHkoKSAmJiB1bmlx
dWVGYW1pbGllcy5hZGQoZmFtaWx5QXRvbSkuaXNOZXdFbnRyeSkKKyAgICAgICAgICAgIGZhbWls
eU9yZGVyLmFwcGVuZChmYW1pbHlBdG9tKTsKICAgICB9CiAKICAgICBIYXNoU2V0PENTU0ZvbnRG
YWNlKj4gcmVzdWx0Q29uc3RpdHVlbnRzOworICAgIGF1dG8gcmVxdWVzdCA9IGNvbXB1dGVGb250
U2VsZWN0aW9uUmVxdWVzdCgqZm9udCk7CiAgICAgZm9yIChhdXRvIGNvZGVQb2ludCA6IGNvZGVQ
b2ludHNGcm9tU3RyaW5nKHN0cmluZykpIHsKICAgICAgICAgYm9vbCBmb3VuZCA9IGZhbHNlOwog
ICAgICAgICBmb3IgKGF1dG8mIGZhbWlseSA6IGZhbWlseU9yZGVyKSB7Cg==
</data>

          </attachment>
      

    </bug>

</bugzilla>