Почему мой файл docx, xlsx, pptx поврежден?

ПРОБЛЕМА :

Мне нужно, чтобы файлы на моем сервере были зашифрованы, и он отлично работает для .txt, .doc, .xls, .ppt, но не для .docx, .xlsx и .pptx.

Проблема, когда я пытаюсь отредактировать docx (или xlsx, pptx), заключается в том, что файл повреждается из-за того, как я шифрую/дешифрую, поскольку это неправильный способ редактирования docx. Поэтому, когда Microsoft Word пытается открыть его, он говорит, что он поврежден, и открывает его как «Document1.docx», а не как «MyFileName.docx», и при сохранении мне нужно снова указать имя, а с pptx я даже должен дать путь к папке webdav, в которой находится документ.

ВОПРОС :

Есть ли способ сохранить его в нужном месте, не вводя путь?

КОД :

Вот код, который я использую для шифрования файлов:

$ext = explode( '.', basename($path));
if (in_array("doc", $ext) || in_array("docx", $ext)) {
    $handle = fopen("$davPath/$path", "rb");
    $data_file = fread($handle, filesize("$davPath/$path"));
    fclose($handle);
} else {            
    $data_file = file_get_contents("$davPath/$path");
}

$encrypt_data_file = $encryption->encrypt($data_file);

if (file_put_contents("$davPath/encrypt_" . basename($path),$encrypt_data_file)) {
    unlink("$davPath/" . basename($path));
    rename("$davPath/encrypt_" . basename($path),"$davPath/" . basename($path));
    return true;
} else {
    return false;
}

И вот код, который я использую для их расшифровки:

$ext = explode( '.', basename($uri));
if(is_file($davPath."/".$uri)) {
    if (in_array("doc", $ext) || in_array("docx", $ext)) {
        $handle = fopen("$davPath/$uri", "rb");
        $data_file = fread($handle, filesize("$davPath/$uri"));
        fclose($handle);
    } else {
        $data_file = file_get_contents("$davPath/$uri");
    }   
}
if ($data_file != false) {
    $decrypt_data_file = $encryption->decrypt($data_file);

    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename='.basename($uri));
    header('Content-Location: '.$_SERVER['SCRIPT_URI']);
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    ob_clean();
    flush();
    echo $decrypt_data_file;
    return false;
}

PS: я нашел обходной путь, который состоит в том, чтобы файл расшифровывался на сервере во время модификации, но я бы очень хотел этого не делать.


person cilmela    schedule 03.07.2014    source источник
comment
Действительно ли файл поврежден (например, содержимое не отображается) или просто путь к файлу при сохранении неверен? Во втором случае я думаю, что это должна быть просто возможность указать слову, где сохранить файл при запуске слова (с аргументом cli);   -  person edi9999    schedule 04.07.2014
comment
Просто путь к файлу, но я использую библиотеку ItHit Ajax и их метод EditDocument, поэтому я не знаю, как добавить параметр, чтобы указать слово, где сохранить   -  person cilmela    schedule 04.07.2014
comment
Я не думаю, что это имеет какое-либо отношение к вашему PHP-коду. Не могли бы вы рассказать больше о библиотеке Ajax, которую вы используете?   -  person edi9999    schedule 04.07.2014
comment
Это библиотека для редактирования документов на сервере webdav. Дополнительную информацию см. на их сайте webdavsystem.com/ajax. .   -  person cilmela    schedule 04.07.2014
comment
Я действительно думаю, что проблема с моим PHP-кодом, потому что, когда я пытаюсь открыть docx с помощью WinRAR, он говорит, что архив поврежден и не может его открыть.   -  person cilmela    schedule 04.07.2014
comment
Ну чем ваш docx испорчен... не понимаю. Вы сказали, что неверным был только путь к файлу.   -  person edi9999    schedule 04.07.2014
comment
Извините, я не был ясен, потому что я неправильно понял. Вы говорили о том, что контент не отображается, но библиотеке действительно удается открыть его, поэтому контент отображается. Но да, файл поврежден. Извините за недопонимание   -  person cilmela    schedule 04.07.2014
comment
В прошлый раз, когда у меня была такая проблема, я использовал шестнадцатеричный редактор, чтобы посмотреть, в чем разница. stackoverflow.com/questions/18243668/ . Можете ли вы сказать, что отличается?   -  person edi9999    schedule 04.07.2014
comment
Что мне нужно для сравнения? Документ перед любым шифрованием/дешифрованием и один после шифрования/дешифрования?   -  person cilmela    schedule 04.07.2014
comment
Да, точно. Например, мы увидим, отличаются ли только некоторые байты, или те, что в начале, или те, что в конце.   -  person edi9999    schedule 04.07.2014


Ответы (2)


Ваша проблема решена, но я хотел бы добавить ответ на нее.

Если у вас есть поврежденный docx, вот несколько шагов, чтобы выяснить, что не так:

Во-первых, попробуйте распаковать zip. Если это работает, ваша проблема связана с содержимым docx. Если распаковка не работает, ваш zip, похоже, поврежден.

Проблемы с содержимым docx

Когда вы откроете docx, Word, вероятно, скажет вам, в чем проблема, если zip не поврежден.

Например, он скажет вам: Parse error on line 213 of document.xml

Вот «нормальная» структура docx после распаковки.

+--docProps
|  +  app.xml
|  \  core.xml
+  res.log
+--word //this folder contains most of the files that control the content of the document
|  +  document.xml //Is the actual content of the document
|  +  endnotes.xml
|  +  fontTable.xml
|  +  footer1.xml //Containst the elements in the footer of the document
|  +  footnotes.xml
|  +--media //This folder contains all images embedded in the word
|  |  \  image1.jpeg
|  +  settings.xml
|  +  styles.xml
|  +  stylesWithEffects.xml
|  +--theme
|  |  \  theme1.xml
|  +  webSettings.xml
|  \--_rels
|     \  document.xml.rels //this document tells word where the images are situated
+  [Content_Types].xml
\--_rels
   \  .rels

Как показано в вики тега docx.

Поврежденный почтовый индекс

Если zip поврежден, в большинстве случаев это какие-то символы в начале или в конце файла, которых там быть не должно (или должно быть, а не быть).

Лучше всего иметь действительный docx одного и того же документа и использовать шестнадцатеричное представление обоих документов, чтобы увидеть, в чем разница.

Я обычно использую для этого инструмент hexdiff (apt-get install hexdiff).

Это обычно показывает вам, где расположены дополнительные символы.

Довольно часто проблема заключается в том, что у вас неправильные заголовки.

person edi9999    schedule 07.07.2014

Благодаря предложению edi9999 я использовал шестнадцатеричный редактор, чтобы посмотреть различия между незашифрованным/расшифрованным docx и зашифрованным/расшифрованным.

Единственная разница в том, что в конце первого (не поврежденного) есть 3 раза «00», которых нет в поврежденном.

Решение для отсутствия поврежденного docx состояло в том, чтобы добавить 3 раза «\ 0» в конец моих расшифрованных данных. И теперь он работает отлично!

Для docx и pptx это 3 раза «\0», а для xlsx — 4 раза.

person cilmela    schedule 04.07.2014
comment
Я предполагаю, что это проблема с вашей библиотекой дешифратора шифратора, которая вызывает проблему (например, возможно, игнорирование нулевых значений в конце). Вы используете это: github.com/o/crypt-php? - person edi9999; 07.07.2014
comment
Нет, я использую свои собственные методы шифрования/дешифрования с помощью mcrypt и base64_encode/decode. Но я не против добавить \0 в конце моих данных. В любом случае большое спасибо за вашу помощь! - person cilmela; 07.07.2014