<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Обратно инженерство на PPTX on File Format Blog</title>
    <link>https://blog.fileformat.com/bg/tag/%D0%BE%D0%B1%D1%80%D0%B0%D1%82%D0%BD%D0%BE-%D0%B8%D0%BD%D0%B6%D0%B5%D0%BD%D0%B5%D1%80%D1%81%D1%82%D0%B2%D0%BE-%D0%BD%D0%B0-pptx/</link>
    <description>Recent content in Обратно инженерство на PPTX on File Format Blog</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>bg</language>
    <lastBuildDate>Wed, 16 Sep 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.fileformat.com/bg/tag/%D0%BE%D0%B1%D1%80%D0%B0%D1%82%D0%BD%D0%BE-%D0%B8%D0%BD%D0%B6%D0%B5%D0%BD%D0%B5%D1%80%D1%81%D1%82%D0%B2%D0%BE-%D0%BD%D0%B0-pptx/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Обратно инженерство на PPTX: Разбиране на вътрешната структура на PowerPoint файловете</title>
      <link>https://blog.fileformat.com/bg/presentation/pptx-reverse-engineering-understanding-powerpoint-files-internally/</link>
      <pubDate>Wed, 16 Sep 2026 00:00:00 +0000</pubDate>
      
      <guid>https://blog.fileformat.com/bg/presentation/pptx-reverse-engineering-understanding-powerpoint-files-internally/</guid>
      <description>Открийте какво всъщност се крие вътре в файл `.pptx`. Научете как работят OpenXML пакетиране, графове на връзки, форми и чертожен маркъп зад кулисите.</description>
      <content:encoded><![CDATA[<p><strong>Последно актуализирано</strong>: 16 септ., 2026</p>
<figure class="align-center ">
    <img loading="lazy" src="images/pptx-reverse-engineering-understanding-powerpoint-files-internally.png#center"
         alt="PPTX Reverse Engineering: Understanding PowerPoint Files Internally"/> 
</figure>

<hr>
<h2 id="обратно-инженерство-pptx4-файлове-ръководство-за-разработчици">Обратно инженерство <a href="https://docs.fileformat.com/presentation/pptx/">PPTX</a> Файлове: Ръководство за разработчици</h2>
<p>Съвременните презентационни набори захранват всичко от инвеститорски предложения до вътрешни тримесечни метрики. Но ако някога сте се наложило да извличате текст програмено, да заменяте шаблони по време на изпълнение, да създавате автоматизирани генератори на слайдове или да пречиствате поверителни презентации, вероятно бързо сте осъзнали нещо: стандартните библиотеки за презентации на високо ниво могат да се чувстват като непредсказуем черен кутия.</p>
<p>Когато библиотеки като <a href="https://products.fileformat.com/presentation/python/python-pptx/"><code>python-pptx</code></a>, <a href="https://products.fileformat.com/presentation/java/apache-poi-xslf/">Apache POI</a> или <a href="https://products.fileformat.com/presentation/net/openxmlsdk/">OpenXML SDK</a> достигнат своите ограничения — или въведат недокументирани грешки в оформлението — единственият изход е през тях. Трябва да разберете какво всъщност е PowerPoint презентация на ниво байтове и схема.</p>
<p>В този задълбочен преглед ще разкрием завесата на формата <code>.pptx</code>, ще разопаковаме вътрешната му структура, проследим графа на взаимоотношенията, ще разгледаме йерархиите на рисуване и ще разгледаме практични стратегии за обратен инженеринг, инспектиране и манипулиране на презентации с чист код.</p>
<h2 id="1-какво-всъщност-е-файл-pptx">1. Какво всъщност е файл <code>.pptx</code>?</h2>
<p>В същността си, файлът <code>.pptx</code> не е собственически монолитен бинарен файл като древния формат <code>.ppt</code> от 90-те години. Откакто Microsoft представи Office Open XML (ECMA-376 и ISO/IEC 29500), съвременните Office документи са <strong>архиви според Open Packaging Conventions (OPC)</strong>.</p>
<p>На прост английски: <strong>файлът <code>.pptx</code> е просто zip архив, съдържащ XML документи и медийни ресурси, организирани в детерминистично дърво от директории.</strong></p>
<p>Можете да докажете това за секунди, като използвате стандартни инструменти в терминала:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Rename the extension and unpack it</span>
</span></span><span style="display:flex;"><span>cp presentation.pptx presentation.zip
</span></span><span style="display:flex;"><span>unzip presentation.zip -d presentation_unpacked/
</span></span><span style="display:flex;"><span>cd presentation_unpacked/
</span></span><span style="display:flex;"><span>tree -L <span style="color:#ae81ff">2</span>
</span></span></code></pre></div><p>Полученото дърво от директории изглежда изключително последователно:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>.
</span></span><span style="display:flex;"><span>├── [Content_Types].xml
</span></span><span style="display:flex;"><span>├── _rels/
</span></span><span style="display:flex;"><span>│   └── .rels
</span></span><span style="display:flex;"><span>├── docProps/
</span></span><span style="display:flex;"><span>│   ├── app.xml
</span></span><span style="display:flex;"><span>│   └── core.xml
</span></span><span style="display:flex;"><span>└── ppt/
</span></span><span style="display:flex;"><span>    ├── presentation.xml
</span></span><span style="display:flex;"><span>    ├── _rels/
</span></span><span style="display:flex;"><span>    ├── slides/
</span></span><span style="display:flex;"><span>    ├── slideLayouts/
</span></span><span style="display:flex;"><span>    ├── slideMasters/
</span></span><span style="display:flex;"><span>    ├── theme/
</span></span><span style="display:flex;"><span>    └── media/
</span></span></code></pre></div><p>Всеки един визуален ресурс, преход, наследяване на главния слайд, координатите на текстовото поле и векторната графика са кодифицирани в тази йерархия от файлове.</p>
<h2 id="2-анатомия-на-пакета-ключови-подсистеми">2. Анатомия на пакета: ключови подсистеми</h2>
<p>За да разшифровате презентациите ефективно, трябва да разберете отговорностите на всеки компонент от най-горното ниво.</p>
<h3 id="content_typesxml"><code>[Content_Types].xml</code></h3>
<p>Това е входният манифест за OPC четеца. Той съпоставя файлови разширения и явни вътрешни имена на части със стандартизирани MIME/типове съдържание. Ако създадете нов слайд или добавите изображение и не го декларирате в <code>[Content_Types].xml</code>, PowerPoint ще обяви презентацията за повредена и ще подкане за възстановяване.</p>
<p>Примерен фрагмент:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#f92672">&lt;Types</span> <span style="color:#a6e22e">xmlns=</span><span style="color:#e6db74">&#34;http://schemas.openxmlformats.org/package/2006/content-types&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&lt;Default</span> <span style="color:#a6e22e">Extension=</span><span style="color:#e6db74">&#34;xml&#34;</span> <span style="color:#a6e22e">ContentType=</span><span style="color:#e6db74">&#34;application/xml&#34;</span><span style="color:#f92672">/&gt;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&lt;Default</span> <span style="color:#a6e22e">Extension=</span><span style="color:#e6db74">&#34;rels&#34;</span> <span style="color:#a6e22e">ContentType=</span><span style="color:#e6db74">&#34;application/vnd.openxmlformats-package.relationships+xml&#34;</span><span style="color:#f92672">/&gt;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&lt;Default</span> <span style="color:#a6e22e">Extension=</span><span style="color:#e6db74">&#34;png&#34;</span> <span style="color:#a6e22e">ContentType=</span><span style="color:#e6db74">&#34;image/png&#34;</span><span style="color:#f92672">/&gt;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&lt;Override</span> <span style="color:#a6e22e">PartName=</span><span style="color:#e6db74">&#34;/ppt/presentation.xml&#34;</span> 
</span></span><span style="display:flex;"><span>            <span style="color:#a6e22e">ContentType=</span><span style="color:#e6db74">&#34;application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml&#34;</span><span style="color:#f92672">/&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">&lt;/Types&gt;</span>
</span></span></code></pre></div><h3 id="графика-на-връзките-_rels">Графика на връзките <code>_rels/</code></h3>
<p>Една от най-важните концепции в OpenXML е <strong>индирация чрез връзки</strong>. Частите рядко сочат директно към сурови файлови пътища. Вместо това, файл (например <code>slide1.xml</code>) има свързан файл с връзки, разположен в съседна папка <code>_rels</code> (например <code>_rels/slide1.xml.rels</code>).</p>
<p>Връзките определят:</p>
<ul>
<li>Хипервръзки (<code>r:id=&quot;rId2&quot;</code>, TargetMode=&ldquo;External&rdquo;)</li>
<li>Изображения и аудио записи, съхранени в <code>ppt/media/</code></li>
<li>Указатели за наследяване на оформление (<code>slideLayout1.xml</code>)</li>
<li>Слайдове с бележки, коментари и вградени шрифтове</li>
</ul>
<h3 id="docprops-метаданни"><code>docProps/</code> (Метаданни)</h3>
<ul>
<li><strong><code>core.xml</code></strong>: Dublin Core метаданни — автор, заглавие, дата на създаване, времеви печат на модификация.</li>
<li><strong><code>app.xml</code></strong>: Специфични за приложението статистики — версия на PowerPoint, общ брой слайдове, брой скрити слайдове, брой думи, имена на шаблони за презентации.</li>
</ul>
<h3 id="ppt-презентационният-двигател"><code>ppt/</code> (Презентационният двигател)</h3>
<p>Тук се намира действителната презентация:</p>
<ul>
<li><strong><code>presentation.xml</code></strong>: Главният гръбнак. Той регистрира ID‑тата на слайдовете, размерите им, препратки към главния бележник и настройките по подразбиране за шрифтовете.</li>
<li><strong><code>slides/</code></strong>: Отделните слайдове (<code>slide1.xml</code>, <code>slide2.xml</code> и др.).</li>
<li><strong><code>slideLayouts/</code></strong>: Главни структурни шаблони (Заглавен слайд, Две колони, Заглавие на раздел).</li>
<li><strong><code>slideMasters/</code></strong>: Глобални стилове, палитри по подразбиране, фонови запълнения и наследяване на заместители.</li>
<li><strong><code>theme/</code></strong>: Цветови палитри (акцент 1 до 6, тъмни/светли вариации) и схеми за шрифтове (главни/второстепенни шрифтове).</li>
<li><strong><code>media/</code></strong>: Необработени изображения (PNG, JPEG, SVG), аудио и видео файлове.</li>
</ul>
<h2 id="3-разглобяване-на-слайд-диалектите-presentationml-p-и-drawingml-a">3. Разглобяване на слайд: диалектите PresentationML (<code>p:</code>) и DrawingML (<code>a:</code>)</h2>
<p>Когато отворите <code>ppt/slides/slide1.xml</code>, срещате две основни XML пространства от имена:</p>
<ol>
<li><strong>PresentationML (<code>p:</code>)</strong>: Управлява структурните елементи за представяне (слайдове, дървета от форми, групи платно).</li>
<li><strong>DrawingML (<code>a:</code>)</strong>: Управлява типографията, геометрията, 2D координатите, градиентните запълнения и векторното рендериране.</li>
</ol>
<p>Ето опростен пример за това как изглежда стандартна текстова форма:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#f92672">&lt;p:sp&gt;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#75715e">&lt;!-- 1. Non-visual shape properties (Identifiers, names) --&gt;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&lt;p:nvSpPr&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;p:cNvPr</span> <span style="color:#a6e22e">id=</span><span style="color:#e6db74">&#34;4&#34;</span> <span style="color:#a6e22e">name=</span><span style="color:#e6db74">&#34;Title Box 1&#34;</span><span style="color:#f92672">/&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;p:cNvSpPr&gt;</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&lt;a:spLocks</span> <span style="color:#a6e22e">noGrp=</span><span style="color:#e6db74">&#34;1&#34;</span><span style="color:#f92672">/&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;/p:cNvSpPr&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;p:nvPr&gt;</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&lt;p:ph</span> <span style="color:#a6e22e">type=</span><span style="color:#e6db74">&#34;title&#34;</span><span style="color:#f92672">/&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;/p:nvPr&gt;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&lt;/p:nvSpPr&gt;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#75715e">&lt;!-- 2. Visual shape properties (Position, size, geometry) --&gt;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&lt;p:spPr&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;a:xfrm&gt;</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&lt;a:off</span> <span style="color:#a6e22e">x=</span><span style="color:#e6db74">&#34;1524000&#34;</span> <span style="color:#a6e22e">y=</span><span style="color:#e6db74">&#34;1143000&#34;</span><span style="color:#f92672">/&gt;</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&lt;a:ext</span> <span style="color:#a6e22e">cx=</span><span style="color:#e6db74">&#34;9144000&#34;</span> <span style="color:#a6e22e">cy=</span><span style="color:#e6db74">&#34;1828800&#34;</span><span style="color:#f92672">/&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;/a:xfrm&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;a:prstGeom</span> <span style="color:#a6e22e">prst=</span><span style="color:#e6db74">&#34;rect&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&lt;a:avLst/&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;/a:prstGeom&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;a:solidFill&gt;</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&lt;a:schemeClr</span> <span style="color:#a6e22e">val=</span><span style="color:#e6db74">&#34;accent1&#34;</span><span style="color:#f92672">/&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;/a:solidFill&gt;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&lt;/p:spPr&gt;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#75715e">&lt;!-- 3. Text Body (Paragraphs, runs, styling) --&gt;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&lt;p:txBody&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;a:bodyPr</span> <span style="color:#a6e22e">rtlCol=</span><span style="color:#e6db74">&#34;0&#34;</span> <span style="color:#a6e22e">anchor=</span><span style="color:#e6db74">&#34;ctr&#34;</span><span style="color:#f92672">/&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;a:lstStyle/&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;a:p&gt;</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&lt;a:r&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&lt;a:rPr</span> <span style="color:#a6e22e">lang=</span><span style="color:#e6db74">&#34;en-US&#34;</span> <span style="color:#a6e22e">sz=</span><span style="color:#e6db74">&#34;3200&#34;</span> <span style="color:#a6e22e">b=</span><span style="color:#e6db74">&#34;1&#34;</span><span style="color:#f92672">/&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&lt;a:t&gt;</span>Mission Critical Architecture<span style="color:#f92672">&lt;/a:t&gt;</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&lt;/a:r&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;/a:p&gt;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&lt;/p:txBody&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">&lt;/p:sp&gt;</span>
</span></span></code></pre></div><h3 id="ключови-единици-за-измерване-emu-и-стотни-от-точка">Ключови единици за измерване: EMU и стотни от точка</h3>
<p>Обърнете внимание на числата за координатите в <code>&lt;a:xfrm&gt;</code>:</p>
<ul>
<li><code>x=&quot;1524000&quot;</code></li>
<li><code>cx=&quot;9144000&quot;</code></li>
</ul>
<p>Това са <strong>английски метрични единици (EMUs)</strong>.</p>
<ul>
<li>$1 \text{ inch} = 914,400 \text{ EMUs}$</li>
<li>$1 \text{ cm} = 360,000 \text{ EMUs}$</li>
<li>$1 \text{ pt} = 12,700 \text{ EMUs}$</li>
</ul>
<p>EMUs позволяват на цели числа да представят точни дроби както на инчове, така и на милиметри, без грешки от закръгляне с плаваща запетая в различни хардуерни архитектури.</p>
<p>Обърнете също внимание на размера на шрифта:</p>
<ul>
<li><code>sz=&quot;3200&quot;</code> означава <strong>32.00 pt</strong>. Размерите на шрифта в DrawingML се измерват в стотни от точка.</li>
</ul>
<h2 id="4-верига-на-наследяване-защо-фигурите-наследяват-невидими-стилове">4. Верига на наследяване: защо фигурите наследяват невидими стилове</h2>
<p>Един от най-често срещаните капани при обратното инженерство на PPTX файлове е предположението, че визуалният стил на форма е напълно деклариран в собствения си <code>slideX.xml</code>.</p>
<p>В действителност, OpenXML се базира на строг <strong>четиристепенен каскаден модел на наследяване</strong>:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>[Theme: ppt/theme/theme1.xml]
</span></span><span style="display:flex;"><span>              │
</span></span><span style="display:flex;"><span>              ▼
</span></span><span style="display:flex;"><span>[Slide Master: ppt/slideMasters/slideMaster1.xml]
</span></span><span style="display:flex;"><span>              │
</span></span><span style="display:flex;"><span>              ▼
</span></span><span style="display:flex;"><span>[Slide Layout: ppt/slideLayouts/slideLayout1.xml]
</span></span><span style="display:flex;"><span>              │
</span></span><span style="display:flex;"><span>              ▼
</span></span><span style="display:flex;"><span>[Slide: ppt/slides/slide1.xml]
</span></span></code></pre></div><p>Ако текстовото поле в <code>slide1.xml</code> съдържа:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#f92672">&lt;a:p&gt;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&lt;a:r&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;a:t&gt;</span>Revenue Projections<span style="color:#f92672">&lt;/a:t&gt;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&lt;/a:r&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">&lt;/a:p&gt;</span>
</span></span></code></pre></div><p>В елемента <code>&lt;a:r&gt;</code> не е зададено семейство шрифтове, нито явен цвят, нито размер. За да разберете как PowerPoint визуализира този текст, вашият парсер трябва:</p>
<ol>
<li>Идентифицирайте типа на заместителя (<code>&lt;p:ph type=&quot;title&quot;/&gt;</code>).</li>
<li>Прочетете оформлението, посочено в <code>slide1.xml.rels</code>.</li>
<li>Проверете дали <code>slideLayout1.xml</code> предоставя замени за стила на този заместител.</li>
<li>Върнете се към <code>slideMaster1.xml</code> за подразбиращите се стилове на текста в заглавието.</li>
<li>Проследете цветови токени като <code>accent1</code> или <code>tx1</code> в <code>theme1.xml</code>, за да намерите шестнадесетичния код на цвета.</li>
</ol>
<p>Ако пропуснете тази графика на наследяване, вашият парсер ще прочете неправилно стиловете, ще пропусне шрифтове, размери на шрифта и котви на оформлението.</p>
<h2 id="5-практичен-процес-на-обратен-инженеринг">5. Практичен процес на обратен инженеринг</h2>
<p>Когато трябва да разследвате как дадена функция на PowerPoint работи под капака (например, морфинг преходи, сложни таблици, векторни пътеки), следвайте този емпиричен подход:</p>
<h3 id="стъпка-1-създаване-на-минимална-diff-pair">Стъпка 1: Създаване на минимална &ldquo;Diff Pair&rdquo;</h3>
<ol>
<li>Отворете PowerPoint и създайте празен слайд.</li>
<li>Запазете го като <code>before.pptx</code>.</li>
<li>Приложете точно едната промяна, която искате да разберете (например, добавете сенка към кръг, променете стила на точка, вмъкнете вградено видео).</li>
<li>Запазете го като <code>after.pptx</code>.</li>
</ol>
<h3 id="стъпка-2-разархивиране-на-двете-архиви">Стъпка 2: Разархивиране на двете архиви</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>unzip before.pptx -d before/
</span></span><span style="display:flex;"><span>unzip after.pptx -d after/
</span></span></code></pre></div><h3 id="стъпка-3-форматиране-на-xml">Стъпка 3: Форматиране на XML</h3>
<p>Суровият XML в архивите на Office обикновено е без отстъпи и нови редове. Преди сравняване, форматирайте файловете:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>find before/ after/ -name <span style="color:#e6db74">&#34;*.xml&#34;</span> -exec xmllint --format <span style="color:#f92672">{}</span> --output <span style="color:#f92672">{}</span> <span style="color:#ae81ff">\;</span>
</span></span></code></pre></div><h3 id="стъпка-4-изпълнение-на-унифициран-diff">Стъпка 4: Изпълнение на унифициран Diff</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>diff -uNr before/ after/ &gt; changes.patch
</span></span></code></pre></div><p>Преглеждането на <code>changes.patch</code> разкрива точния име на етикет, атрибут за пространство от имена и йерархията на контейнера, които PowerPoint е въвел. Това е най-бързият начин да откриете недокументирани или неясни свойства на схемата, без да копаете през хиляди страници от документацията ECMA-376.</p>
<h2 id="6-създаване-на-персонализиран-микромотор-разархивиране-модифициране-повторно-архивиране">6. Създаване на персонализиран микромотор: разархивиране, модифициране, повторно архивиране</h2>
<p>Понякога не искате тежка корпоративна зависимост като Apache POI или Microsoft OpenXML SDK — особено в леки безсървърни среди (AWS Lambda, Cloudflare Workers, edge възли).</p>
<p>Ето самостоятелен Python шаблон, който демонстрира как безопасно да разархивирате PPTX в паметта, да вмъкнете персонализирани данни с помощта на стандартните библиотеки и да го пакетирайте отново:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">import</span> zipfile
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> io
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> xml.etree.ElementTree <span style="color:#66d9ef">as</span> ET
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">modify_slide_title</span>(input_pptx_bytes: bytes, new_title: str) <span style="color:#f92672">-&gt;</span> bytes:
</span></span><span style="display:flex;"><span>    input_zip <span style="color:#f92672">=</span> zipfile<span style="color:#f92672">.</span>ZipFile(io<span style="color:#f92672">.</span>BytesIO(input_pptx_bytes))
</span></span><span style="display:flex;"><span>    output_buffer <span style="color:#f92672">=</span> io<span style="color:#f92672">.</span>BytesIO()
</span></span><span style="display:flex;"><span>    
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">with</span> zipfile<span style="color:#f92672">.</span>ZipFile(output_buffer, <span style="color:#e6db74">&#34;w&#34;</span>, zipfile<span style="color:#f92672">.</span>ZIP_DEFLATED) <span style="color:#66d9ef">as</span> output_zip:
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">for</span> item <span style="color:#f92672">in</span> input_zip<span style="color:#f92672">.</span>infolist():
</span></span><span style="display:flex;"><span>            content <span style="color:#f92672">=</span> input_zip<span style="color:#f92672">.</span>read(item<span style="color:#f92672">.</span>filename)
</span></span><span style="display:flex;"><span>            
</span></span><span style="display:flex;"><span>            <span style="color:#75715e"># Target slide 1</span>
</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">if</span> item<span style="color:#f92672">.</span>filename <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;ppt/slides/slide1.xml&#34;</span>:
</span></span><span style="display:flex;"><span>                namespaces <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>                    <span style="color:#e6db74">&#39;p&#39;</span>: <span style="color:#e6db74">&#39;http://schemas.openxmlformats.org/presentationml/2006/main&#39;</span>,
</span></span><span style="display:flex;"><span>                    <span style="color:#e6db74">&#39;a&#39;</span>: <span style="color:#e6db74">&#39;http://schemas.openxmlformats.org/drawingml/2006/main&#39;</span>
</span></span><span style="display:flex;"><span>                }
</span></span><span style="display:flex;"><span>                
</span></span><span style="display:flex;"><span>                <span style="color:#75715e"># Register namespaces to preserve prefixes</span>
</span></span><span style="display:flex;"><span>                <span style="color:#66d9ef">for</span> prefix, uri <span style="color:#f92672">in</span> namespaces<span style="color:#f92672">.</span>items():
</span></span><span style="display:flex;"><span>                    ET<span style="color:#f92672">.</span>register_namespace(prefix, uri)
</span></span><span style="display:flex;"><span>                    
</span></span><span style="display:flex;"><span>                root <span style="color:#f92672">=</span> ET<span style="color:#f92672">.</span>fromstring(content)
</span></span><span style="display:flex;"><span>                
</span></span><span style="display:flex;"><span>                <span style="color:#75715e"># Find title placeholder text run</span>
</span></span><span style="display:flex;"><span>                <span style="color:#66d9ef">for</span> title_run <span style="color:#f92672">in</span> root<span style="color:#f92672">.</span>findall(<span style="color:#e6db74">&#34;.//p:sp[p:nvSpPr/p:nvPr/p:ph[@type=&#39;title&#39;]]//a:t&#34;</span>, namespaces):
</span></span><span style="display:flex;"><span>                    title_run<span style="color:#f92672">.</span>text <span style="color:#f92672">=</span> new_title
</span></span><span style="display:flex;"><span>                    <span style="color:#66d9ef">break</span>
</span></span><span style="display:flex;"><span>                
</span></span><span style="display:flex;"><span>                content <span style="color:#f92672">=</span> ET<span style="color:#f92672">.</span>tostring(root, encoding<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;utf-8&#34;</span>, xml_declaration<span style="color:#f92672">=</span><span style="color:#66d9ef">True</span>)
</span></span><span style="display:flex;"><span>            
</span></span><span style="display:flex;"><span>            output_zip<span style="color:#f92672">.</span>writestr(item, content)
</span></span><span style="display:flex;"><span>            
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> output_buffer<span style="color:#f92672">.</span>getvalue()
</span></span></code></pre></div><h3 id="ключови-подводни-камъни-при-модифициране-на-файлове-на-ниво-сурови-байтове">Ключови подводни камъни при модифициране на файлове на ниво сурови байтове:</h3>
<ol>
<li><strong>Запазване на пространството от имена</strong>: XML парсерите често пренаписват префикси (<code>xmlns:p</code> може да се превърне в <code>xmlns:ns0</code>). Въпреки че е валиден XML, строгата вътрешна валидация на схемата в PowerPoint понякога отхвърля нестандартни псевдоними на префикси. Регистрирайте пространствата от имена изрично.</li>
<li><strong>Методи за компресия на ZIP</strong>: Уверете се, че записвате файловете обратно, използвайки стандартната дефлат компресия (<code>zipfile.ZIP_DEFLATED</code>).</li>
<li><strong>Изпразване на потока</strong>: Винаги проверявайте, че вашият ZIP буфер се затваря и изпразва напълно, преди да изпратите байтовете надолу по веригата.</li>
<li><strong>Запазване на връзките</strong>: Ако премахнете слайд, трябва също да премахнете неговия запис от <code>ppt/presentation.xml</code>, да изтриете неговата връзка в <code>ppt/_rels/presentation.xml.rels</code> и да изчистите неговия тип съдържание от <code>[Content_Types].xml</code>.</li>
</ol>
<h2 id="7-съображения-за-производителност-и-сигурност">7. Съображения за производителност и сигурност</h2>
<p>Обратното инженерство на PPTX файлове не е само за редактиране на слайдове; то също включва одитиране на това, което влиза във вашите системи.</p>
<h3 id="сигурност-миллиард-смехове--xxe">Сигурност: Миллиард Смехове &amp; XXE</h3>
<p>Тъй като PPTX файловете парсират XML, всеки сървърен процес, който приема потребителски представени презентации, е уязвим към:</p>
<ul>
<li><strong>XML външна ентитет (XXE) инжекция</strong>: Злонамерен XML, опитващ се да достъпи <code>/etc/passwd</code> или да запита вътрешни облачни метаданни (<code>http://169.254.169.254/</code>).</li>
<li><strong>Атаки с разширяване на ентитети (Billion Laughs)</strong>: Експоненциални цикли на ентитети, изчерпващи RAM паметта на системата.</li>
</ul>
<p><strong>Митигиране</strong>: Винаги деактивирайте <code>resolve_entities</code>, <code>load_dtd</code> и външното резолвиране на мрежа във вашия XML парсер (например, като използвате <code>defusedxml</code> в Python).</p>
<h3 id="сигурност-макро-полезни-товари-и-скрити-потоци">Сигурност: Макро полезни товари и скрити потоци</h3>
<p>Проверявайте файловете за съдържание <code>.pptm</code>, скрито под разширения <code>.pptx</code>. Обърнете внимание на <code>ppt/vbaProject.bin</code>, който съдържа компилиран Visual Basic код. В стандартните <code>.pptx</code> файлове VBA кодът е забранен; откриването на референции към двоични полезни товари в отношенията трябва незабавно да задейства флагове за карантина.</p>
<h2 id="заключение">Заключение</h2>
<p>Обратното инженерство на <code>.pptx</code> файлове разкрива мистерията около софтуера за презентации. След като разберете, че файловете на PowerPoint са просто структуриран zip пакет, пълен с координати, референции към схеми и XML дървета на отношения, вече не сте ограничени от съществуващите трети страни абстракции.</p>
<p>Независимо дали оптимизирате пропускателната способност на генериране на слайдове, пишете персонализирани автоматизирани санитайзъри или отстранявате проблеми с рендерирането, директният поглед към подлежащата OpenXML архитектура ви дава пълен контрол върху процеса на презентацията.</p>
<h2 id="често-задавани-въпроси-faq">Често задавани въпроси (FAQ)</h2>
<p>**Q: Можете ли да конвертирате .pptx в стандартна папка и да редактирате файловете директно в IDE?</p>
<p><strong>A1:</strong> Да, можете да извлечете архива, да редактирате XML в редактор като VS Code и да препакетирате съдържанието на директорията, за да го отворите отново в PowerPoint.</p>
<p>**Q: Защо PowerPoint казва, че моят ръчно модифициран PPTX файл се нуждае от поправка?</p>
<p><strong>A2:</strong> Това обикновено се случва, ако сте въвели неправилно XML, пропуснете нов ресурс от <code>[Content_Types].xml</code>, или оставите висяща препратка в свързания <code>.rels</code> файл.</p>
<p>**Q: Коя измервателна единица използва PowerPoint за позициите и отстъпите на формите?</p>
<p><strong>A3:</strong> PowerPoint използва английски метрични единици (EMUs), където 1 инч е равен на 914,400 EMUs и 1 точка е равна на 12,700 EMUs.</p>
<p>**Q: Как мога да <a href="https://products.fileformat.com/presentation/python/python-pptx/">програмено извличане</a> на всички изображения от презентация без външни библиотеки?</p>
<p><strong>A4:</strong> Просто отворете файла <code>.pptx</code> с всяка стандартна zip‑утилита и извлечете всички бинарни файлове, намиращи се в директорията <code>ppt/media/</code>.</p>
<p>**Q: Безопасно ли е да се анализират качени от потребители PPTX файлове със стандартни XML парсъри?</p>
<p><strong>A5:</strong> Не, трябва да подсилите вашия парсер или да използвате безопасни обвивки като <code>defusedxml</code>, за да блокирате атаки тип XML External Entity (XXE) и zip‑бомби.</p>
<h2 id="вижте-още">Вижте още</h2>
<ul>
<li><a href="https://blog.fileformat.com/presentation/powerpoint-file-formats/">Файлови формати за презентации в FileFormat.com?</a></li>
<li><a href="https://blog.fileformat.com/presentation/apache-poi-api-to-access-powerpoint-file-formats/">Java API за достъп до файлови формати на PowerPoint</a></li>
<li><a href="https://blog.fileformat.com/presentation/odp-vs-pptx-opendocument-vs-microsoft-powerpoint-format-comparison/">ODP срещу PPTX: Сравнение на формати OpenDocument и Microsoft PowerPoint Presentation</a></li>
<li><a href="https://blog.fileformat.com/presentation/difference-between-ppt-and-pptx/">Разлика между PPT и PPTX</a></li>
<li><a href="https://blog.fileformat.com/presentation/create-presentation-in-java-with-apache-poi-api/">Създаване на PowerPoint презентация в Java с Apache POI API</a></li>
</ul>
<!-- raw HTML omitted -->
]]></content:encoded>
    </item>
    
  </channel>
</rss>
