<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Stephan Bergmann, Author at Collabora Online and Collabora Office</title>
	<atom:link href="https://www.collaboraonline.com/blog/author/sberg/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.collaboraonline.com/blog/author/sberg/</link>
	<description>Secure Document Collaboration, Controlled by You</description>
	<lastBuildDate>Thu, 05 Mar 2026 13:25:12 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.3</generator>

<image>
	<url>https://www.collaboraonline.com/wp-content/uploads/2023/06/collabora-symbols-600-150x150.png</url>
	<title>Stephan Bergmann, Author at Collabora Online and Collabora Office</title>
	<link>https://www.collaboraonline.com/blog/author/sberg/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Pointer in range</title>
		<link>https://www.collaboraonline.com/blog/pointer-in-range/</link>
					<comments>https://www.collaboraonline.com/blog/pointer-in-range/#respond</comments>
		
		<dc:creator><![CDATA[Stephan Bergmann]]></dc:creator>
		<pubDate>Thu, 05 Mar 2026 09:07:55 +0000</pubDate>
				<category><![CDATA[Developer Blog]]></category>
		<guid isPermaLink="false">https://www.collaboraonline.com/?p=56389</guid>

					<description><![CDATA[<p>Mostly for historical reasons, LibreOffice has its own `SvMemoryStream` class (for, you guessed it, writing in-memory streams). For quite a while now, code in the PDF filter used that `SvMemoryStream` in a quite peculiar way: In various places, it would take a pointer to some bytes that had already been written into the `SvMemoryStream`&#8217;s buffer, [&#8230;]</p>
<p>The post <a href="https://www.collaboraonline.com/blog/pointer-in-range/">Pointer in range</a> appeared first on <a href="https://www.collaboraonline.com/">Collabora Online and Collabora Office</a>.</p>
]]></description>
										<content:encoded><![CDATA[		<div data-elementor-type="wp-post" data-elementor-id="56389" class="elementor elementor-56389" data-elementor-post-type="post">
				<div class="elementor-element elementor-element-1e61cc4d e-flex e-con-boxed e-con e-parent" data-id="1e61cc4d" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-25ba6ab elementor-author-box--avatar-yes elementor-author-box--name-yes elementor-author-box--biography-yes elementor-author-box--link-no elementor-widget elementor-widget-author-box" data-id="25ba6ab" data-element_type="widget" data-widget_type="author-box.default">
				<div class="elementor-widget-container">
							<div class="elementor-author-box">
							<div  class="elementor-author-box__avatar">
					<img decoding="async" src="https://www.collaboraonline.com/wp-content/uploads/2026/03/Stephan-Bergmann-Headshot.jpg" alt="Picture of Stephan Bergmann" loading="lazy">
				</div>
			
			<div class="elementor-author-box__text">
									<div >
						<h4 class="elementor-author-box__name">
							Stephan Bergmann						</h4>
					</div>
				
									<div class="elementor-author-box__bio">
											</div>
				
							</div>
		</div>
						</div>
				</div>
				<div class="elementor-element elementor-element-6988f95 elementor-widget elementor-widget-text-editor" data-id="6988f95" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
									<p>Mostly for historical reasons, LibreOffice has its own `SvMemoryStream` class (for, you guessed it, writing in-memory streams). For quite a while now, code in the PDF filter used that `SvMemoryStream` in a quite peculiar way: In various places, it would take a pointer to some bytes that had already been written into the `SvMemoryStream`&#8217;s buffer, and then call `SvMemoryStream::WriteBytes` to append those bytes a second time. Which indeed works, as long as the call to `WriteBytes` does not need to enlarge the `SvMemoryStream`&#8217;s buffer first&#8212;at which point the pointer to the bytes-to-be-written-a-second-time would point to freed memory.</p>
<p>Interestingly, this never seemed to cause issues in practice. Until, recently, some tests changed and the address-sanitizer builds started to complain about heap-user-after-free issues. Now, one way to fix this would have been to inspect all those places that use that dubious pattern, and change them to first copy the bytes to the side, and pass that copy to `SvMemoryStream::WriteBytes`.</p>
<p>But Noel had the nice idea of instead changing the implementation of `SvMemoryStream`: When `WriteBytes` needs to enlarge the buffer, it now checks whether the pointer to the to-be-written data was coming from within its original buffer. And if yes, it fixes that pointer up to instead point into the enlarged buffer (where the contents of those bytes is guaranteed to be available just fine).</p>
<p>So, how do you check in C++ that a pointer actually points into a range of bytes?</p>								</div>
				</div>
				<div class="elementor-element elementor-element-ccff3ba elementor-widget elementor-widget-text-editor" data-id="ccff3ba" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
									<pre>pData &gt;= pBuf &amp;&amp; pData &lt; (pBuf + nSize)</pre>								</div>
				</div>
				<div class="elementor-element elementor-element-41fc4d7 elementor-widget elementor-widget-text-editor" data-id="41fc4d7" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
									<p>looks innocent enough and should get the job done? Except it doesn&#8217;t. Because C++ has all that fine print. When comparing pointers with relational operators, if they don&#8217;t both point into the same array, the results are unspecified. Which an aggressively optimizing compiler can take advantage of. Either `pData` is within the `pBuf`&#8230;`pBuf + nSize` array, and the above check is true. Or `pData` is pointing at some completely different array, in which case&#8230; Well, the results are unspecified, so why not declare that the check is true in that case as well? Which means the compiler can pretend that the check is always true and isn&#8217;t even needed, and `WriteBytes` will always fix up the pointer that gets passed in to point into the enlarged buffer, even if it originally didn&#8217;t point into the original buffer. Ouch.</p><p>There&#8217;s &lt;<a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3234r1.html">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3234r1.html</a>&gt; &#8220;Utility to check if a pointer is in a given range&#8221; that might bring some guaranteed-to-be-working `std::pointer_in_range` to some future version of C++. Until then, we can make use of `boost::pointer_in_range`.</p>								</div>
				</div>
					</div>
				</div>
				</div>
		<p>The post <a href="https://www.collaboraonline.com/blog/pointer-in-range/">Pointer in range</a> appeared first on <a href="https://www.collaboraonline.com/">Collabora Online and Collabora Office</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.collaboraonline.com/blog/pointer-in-range/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
