<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[214125] trunk/Source</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/214125">214125</a></dd>
<dt>Author</dt> <dd>said@apple.com</dd>
<dt>Date</dt> <dd>2017-03-17 14:51:03 -0700 (Fri, 17 Mar 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>Time channel attack on SVG Filters
https://bugs.webkit.org/show_bug.cgi?id=118689

Reviewed by Simon Fraser.

Source/WebCore:

The time channel attack can happen if the attacker applies FEColorMatrix
or FEConvolveMatrix and provides a matrix which is filled with subnormal
floating point values. Performing floating-point operations on subnormals
is very expensive unless the pixel in the source graphics is black (or
zero). By measuring the time a filter takes to be applied, the attacker
can know whether the pixel he wants to steal from  an iframe is black or
white. By repeating the same process on all the pixels in the iframe, the
attacker can reconstruct the whole page of the iframe.

To fix this issue, the values in the matrices of these filters will clamped
to FLT_MIN. We do not want to consume too much time calculating filtered
pixels because of such tiny values. The difference between applying FLT_MIN
and applying a subnormal should not be even noticeable. Normalizing the
floating-point matrices should happen only at the beginning of the filter
platformApplySoftware().

* platform/graphics/filters/FEColorMatrix.cpp:
(WebCore::FEColorMatrix::platformApplySoftware):
* platform/graphics/filters/FEConvolveMatrix.cpp:
(WebCore::FEConvolveMatrix::fastSetInteriorPixels):
(WebCore::FEConvolveMatrix::fastSetOuterPixels):
(WebCore::FEConvolveMatrix::platformApplySoftware):
* platform/graphics/filters/FEConvolveMatrix.h:
* platform/graphics/filters/FilterEffect.h:
(WebCore::FilterEffect::normalizedFloats):

Source/WTF:

Performing arithmetic operations on subnormal floating-point numbers is
very expensive. Normalizing the floating-point number to the minimum normal
value should accelerate the calculations and there won't be a noticeable
difference in the result since all the subnormal values and the minimum
normal value are all very close to zero.

* wtf/MathExtras.h:
(normalizedFloat):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFwtfMathExtrash">trunk/Source/WTF/wtf/MathExtras.h</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersFEColorMatrixcpp">trunk/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersFEConvolveMatrixcpp">trunk/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersFEConvolveMatrixh">trunk/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfiltersFilterEffecth">trunk/Source/WebCore/platform/graphics/filters/FilterEffect.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (214124 => 214125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog        2017-03-17 21:31:49 UTC (rev 214124)
+++ trunk/Source/WTF/ChangeLog        2017-03-17 21:51:03 UTC (rev 214125)
</span><span class="lines">@@ -1,3 +1,19 @@
</span><ins>+2017-03-17  Said Abou-Hallawa  &lt;sabouhallawa@apple.com&gt;
+
+        Time channel attack on SVG Filters
+        https://bugs.webkit.org/show_bug.cgi?id=118689
+
+        Reviewed by Simon Fraser.
+
+        Performing arithmetic operations on subnormal floating-point numbers is
+        very expensive. Normalizing the floating-point number to the minimum normal
+        value should accelerate the calculations and there won't be a noticeable
+        difference in the result since all the subnormal values and the minimum
+        normal value are all very close to zero.
+
+        * wtf/MathExtras.h:
+        (normalizedFloat):
+
</ins><span class="cx"> 2017-03-11  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Air should be powerful enough to support Tmp-splitting
</span></span></pre></div>
<a id="trunkSourceWTFwtfMathExtrash"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/MathExtras.h (214124 => 214125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/MathExtras.h        2017-03-17 21:31:49 UTC (rev 214124)
+++ trunk/Source/WTF/wtf/MathExtras.h        2017-03-17 21:51:03 UTC (rev 214125)
</span><span class="lines">@@ -209,6 +209,15 @@
</span><span class="cx">     return x &gt; static_cast&lt;float&gt;(std::numeric_limits&lt;int&gt;::min()) &amp;&amp; x &lt; static_cast&lt;float&gt;(std::numeric_limits&lt;int&gt;::max());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline float normalizedFloat(float value)
+{
+    if (value &gt; 0 &amp;&amp; value &lt; std::numeric_limits&lt;float&gt;::min())
+        return std::numeric_limits&lt;float&gt;::min();
+    if (value &lt; 0 &amp;&amp; value &gt; -std::numeric_limits&lt;float&gt;::min())
+        return -std::numeric_limits&lt;float&gt;::min();
+    return value;
+}
+
</ins><span class="cx"> template&lt;typename T&gt; inline bool hasOneBitSet(T value)
</span><span class="cx"> {
</span><span class="cx">     return !((value - 1) &amp; value) &amp;&amp; value;
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (214124 => 214125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2017-03-17 21:31:49 UTC (rev 214124)
+++ trunk/Source/WebCore/ChangeLog        2017-03-17 21:51:03 UTC (rev 214125)
</span><span class="lines">@@ -1,3 +1,36 @@
</span><ins>+2017-03-17  Said Abou-Hallawa  &lt;sabouhallawa@apple.com&gt;
+
+        Time channel attack on SVG Filters
+        https://bugs.webkit.org/show_bug.cgi?id=118689
+
+        Reviewed by Simon Fraser.
+
+        The time channel attack can happen if the attacker applies FEColorMatrix
+        or FEConvolveMatrix and provides a matrix which is filled with subnormal
+        floating point values. Performing floating-point operations on subnormals
+        is very expensive unless the pixel in the source graphics is black (or
+        zero). By measuring the time a filter takes to be applied, the attacker
+        can know whether the pixel he wants to steal from  an iframe is black or
+        white. By repeating the same process on all the pixels in the iframe, the
+        attacker can reconstruct the whole page of the iframe.
+
+        To fix this issue, the values in the matrices of these filters will clamped
+        to FLT_MIN. We do not want to consume too much time calculating filtered
+        pixels because of such tiny values. The difference between applying FLT_MIN
+        and applying a subnormal should not be even noticeable. Normalizing the
+        floating-point matrices should happen only at the beginning of the filter
+        platformApplySoftware().
+
+        * platform/graphics/filters/FEColorMatrix.cpp:
+        (WebCore::FEColorMatrix::platformApplySoftware):
+        * platform/graphics/filters/FEConvolveMatrix.cpp:
+        (WebCore::FEConvolveMatrix::fastSetInteriorPixels):
+        (WebCore::FEConvolveMatrix::fastSetOuterPixels):
+        (WebCore::FEConvolveMatrix::platformApplySoftware):
+        * platform/graphics/filters/FEConvolveMatrix.h:
+        * platform/graphics/filters/FilterEffect.h:
+        (WebCore::FilterEffect::normalizedFloats):
+
</ins><span class="cx"> 2017-03-17  Jer Noble  &lt;jer.noble@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Explicitly resize the audio buffer in RealtimeOutgoingAudioSource.
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersFEColorMatrixcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp (214124 => 214125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp        2017-03-17 21:31:49 UTC (rev 214124)
+++ trunk/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp        2017-03-17 21:51:03 UTC (rev 214125)
</span><span class="lines">@@ -153,21 +153,22 @@
</span><span class="cx"> 
</span><span class="cx">     IntRect imageRect(IntPoint(), resultImage-&gt;logicalSize());
</span><span class="cx">     RefPtr&lt;Uint8ClampedArray&gt; pixelArray = resultImage-&gt;getUnmultipliedImageData(imageRect);
</span><ins>+    Vector&lt;float&gt; values = normalizedFloats(m_values);
</ins><span class="cx"> 
</span><span class="cx">     switch (m_type) {
</span><span class="cx">     case FECOLORMATRIX_TYPE_UNKNOWN:
</span><span class="cx">         break;
</span><span class="cx">     case FECOLORMATRIX_TYPE_MATRIX:
</span><del>-        effectType&lt;FECOLORMATRIX_TYPE_MATRIX&gt;(pixelArray.get(), m_values);
</del><ins>+        effectType&lt;FECOLORMATRIX_TYPE_MATRIX&gt;(pixelArray.get(), values);
</ins><span class="cx">         break;
</span><span class="cx">     case FECOLORMATRIX_TYPE_SATURATE: 
</span><del>-        effectType&lt;FECOLORMATRIX_TYPE_SATURATE&gt;(pixelArray.get(), m_values);
</del><ins>+        effectType&lt;FECOLORMATRIX_TYPE_SATURATE&gt;(pixelArray.get(), values);
</ins><span class="cx">         break;
</span><span class="cx">     case FECOLORMATRIX_TYPE_HUEROTATE:
</span><del>-        effectType&lt;FECOLORMATRIX_TYPE_HUEROTATE&gt;(pixelArray.get(), m_values);
</del><ins>+        effectType&lt;FECOLORMATRIX_TYPE_HUEROTATE&gt;(pixelArray.get(), values);
</ins><span class="cx">         break;
</span><span class="cx">     case FECOLORMATRIX_TYPE_LUMINANCETOALPHA:
</span><del>-        effectType&lt;FECOLORMATRIX_TYPE_LUMINANCETOALPHA&gt;(pixelArray.get(), m_values);
</del><ins>+        effectType&lt;FECOLORMATRIX_TYPE_LUMINANCETOALPHA&gt;(pixelArray.get(), values);
</ins><span class="cx">         setIsAlphaImage(true);
</span><span class="cx">         break;
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersFEConvolveMatrixcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp (214124 => 214125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp        2017-03-17 21:31:49 UTC (rev 214124)
+++ trunk/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp        2017-03-17 21:51:03 UTC (rev 214125)
</span><span class="lines">@@ -267,7 +267,7 @@
</span><span class="cx"> 
</span><span class="cx">     for (int y = yEnd + 1; y &gt; yStart; --y) {
</span><span class="cx">         for (int x = clipRight + 1; x &gt; 0; --x) {
</span><del>-            int kernelValue = m_kernelMatrix.size() - 1;
</del><ins>+            int kernelValue = paintingData.kernelMatrix.size() - 1;
</ins><span class="cx">             int kernelPixel = startKernelPixel;
</span><span class="cx">             int width = m_kernelSize.width();
</span><span class="cx"> 
</span><span class="lines">@@ -278,11 +278,11 @@
</span><span class="cx">                 totals[3] = 0;
</span><span class="cx"> 
</span><span class="cx">             while (kernelValue &gt;= 0) {
</span><del>-                totals[0] += m_kernelMatrix[kernelValue] * static_cast&lt;float&gt;(paintingData.srcPixelArray-&gt;item(kernelPixel++));
-                totals[1] += m_kernelMatrix[kernelValue] * static_cast&lt;float&gt;(paintingData.srcPixelArray-&gt;item(kernelPixel++));
-                totals[2] += m_kernelMatrix[kernelValue] * static_cast&lt;float&gt;(paintingData.srcPixelArray-&gt;item(kernelPixel++));
</del><ins>+                totals[0] += paintingData.kernelMatrix[kernelValue] * static_cast&lt;float&gt;(paintingData.srcPixelArray-&gt;item(kernelPixel++));
+                totals[1] += paintingData.kernelMatrix[kernelValue] * static_cast&lt;float&gt;(paintingData.srcPixelArray-&gt;item(kernelPixel++));
+                totals[2] += paintingData.kernelMatrix[kernelValue] * static_cast&lt;float&gt;(paintingData.srcPixelArray-&gt;item(kernelPixel++));
</ins><span class="cx">                 if (!preserveAlphaValues)
</span><del>-                    totals[3] += m_kernelMatrix[kernelValue] * static_cast&lt;float&gt;(paintingData.srcPixelArray-&gt;item(kernelPixel));
</del><ins>+                    totals[3] += paintingData.kernelMatrix[kernelValue] * static_cast&lt;float&gt;(paintingData.srcPixelArray-&gt;item(kernelPixel));
</ins><span class="cx">                 ++kernelPixel;
</span><span class="cx">                 --kernelValue;
</span><span class="cx">                 if (!--width) {
</span><span class="lines">@@ -347,7 +347,7 @@
</span><span class="cx"> 
</span><span class="cx">     for (int y = height; y &gt; 0; --y) {
</span><span class="cx">         for (int x = width; x &gt; 0; --x) {
</span><del>-            int kernelValue = m_kernelMatrix.size() - 1;
</del><ins>+            int kernelValue = paintingData.kernelMatrix.size() - 1;
</ins><span class="cx">             int kernelPixelX = startKernelPixelX;
</span><span class="cx">             int kernelPixelY = startKernelPixelY;
</span><span class="cx">             int width = m_kernelSize.width();
</span><span class="lines">@@ -361,12 +361,12 @@
</span><span class="cx">             while (kernelValue &gt;= 0) {
</span><span class="cx">                 int pixelIndex = getPixelValue(paintingData, kernelPixelX, kernelPixelY);
</span><span class="cx">                 if (pixelIndex &gt;= 0) {
</span><del>-                    totals[0] += m_kernelMatrix[kernelValue] * static_cast&lt;float&gt;(paintingData.srcPixelArray-&gt;item(pixelIndex));
-                    totals[1] += m_kernelMatrix[kernelValue] * static_cast&lt;float&gt;(paintingData.srcPixelArray-&gt;item(pixelIndex + 1));
-                    totals[2] += m_kernelMatrix[kernelValue] * static_cast&lt;float&gt;(paintingData.srcPixelArray-&gt;item(pixelIndex + 2));
</del><ins>+                    totals[0] += paintingData.kernelMatrix[kernelValue] * static_cast&lt;float&gt;(paintingData.srcPixelArray-&gt;item(pixelIndex));
+                    totals[1] += paintingData.kernelMatrix[kernelValue] * static_cast&lt;float&gt;(paintingData.srcPixelArray-&gt;item(pixelIndex + 1));
+                    totals[2] += paintingData.kernelMatrix[kernelValue] * static_cast&lt;float&gt;(paintingData.srcPixelArray-&gt;item(pixelIndex + 2));
</ins><span class="cx">                 }
</span><span class="cx">                 if (!preserveAlphaValues &amp;&amp; pixelIndex &gt;= 0)
</span><del>-                    totals[3] += m_kernelMatrix[kernelValue] * static_cast&lt;float&gt;(paintingData.srcPixelArray-&gt;item(pixelIndex + 3));
</del><ins>+                    totals[3] += paintingData.kernelMatrix[kernelValue] * static_cast&lt;float&gt;(paintingData.srcPixelArray-&gt;item(pixelIndex + 3));
</ins><span class="cx">                 ++kernelPixelX;
</span><span class="cx">                 --kernelValue;
</span><span class="cx">                 if (!--width) {
</span><span class="lines">@@ -436,6 +436,7 @@
</span><span class="cx">     paintingData.width = paintSize.width();
</span><span class="cx">     paintingData.height = paintSize.height();
</span><span class="cx">     paintingData.bias = m_bias * 255;
</span><ins>+    paintingData.kernelMatrix = normalizedFloats(m_kernelMatrix);
</ins><span class="cx"> 
</span><span class="cx">     // Drawing fully covered pixels
</span><span class="cx">     int clipRight = paintSize.width() - m_kernelSize.width();
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersFEConvolveMatrixh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.h (214124 => 214125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.h        2017-03-17 21:31:49 UTC (rev 214124)
+++ trunk/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.h        2017-03-17 21:51:03 UTC (rev 214125)
</span><span class="lines">@@ -83,6 +83,7 @@
</span><span class="cx">         int width;
</span><span class="cx">         int height;
</span><span class="cx">         float bias;
</span><ins>+        Vector&lt;float&gt; kernelMatrix;
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     FEConvolveMatrix(Filter&amp;, const IntSize&amp;, float, float,
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersFilterEffecth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/FilterEffect.h (214124 => 214125)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/FilterEffect.h        2017-03-17 21:31:49 UTC (rev 214124)
+++ trunk/Source/WebCore/platform/graphics/filters/FilterEffect.h        2017-03-17 21:51:03 UTC (rev 214125)
</span><span class="lines">@@ -26,6 +26,7 @@
</span><span class="cx"> #include &quot;FloatRect.h&quot;
</span><span class="cx"> #include &quot;IntRect.h&quot;
</span><span class="cx"> #include &lt;runtime/Uint8ClampedArray.h&gt;
</span><ins>+#include &lt;wtf/MathExtras.h&gt;
</ins><span class="cx"> #include &lt;wtf/RefCounted.h&gt;
</span><span class="cx"> #include &lt;wtf/RefPtr.h&gt;
</span><span class="cx"> #include &lt;wtf/Vector.h&gt;
</span><span class="lines">@@ -170,6 +171,14 @@
</span><span class="cx">     void forceValidPreMultipliedPixels();
</span><span class="cx"> 
</span><span class="cx">     void clipAbsolutePaintRect();
</span><ins>+    
+    static Vector&lt;float&gt; normalizedFloats(const Vector&lt;float&gt;&amp; values)
+    {
+        Vector&lt;float&gt; normalizedValues(values.size());
+        for (size_t i = 0; i &lt; values.size(); ++i)
+            normalizedValues[i] = normalizedFloat(values[i]);
+        return normalizedValues;
+    }
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     std::unique_ptr&lt;ImageBuffer&gt; m_imageBufferResult;
</span></span></pre>
</div>
</div>

</body>
</html>