GithubHelp home page GithubHelp logo

e8tools / tool1cd Goto Github PK

View Code? Open in Web Editor NEW
109.0 29.0 29.0 6.33 MB

Инструмент для работы с файлами 1CD за авторством Валерия Агеева с адаптацией от сообщества

License: GNU General Public License v3.0

C++ 98.58% C 0.30% CMake 0.84% 1C Enterprise 0.17% QMake 0.10% Batchfile 0.01%
v8unpack tool1cd 1cd

tool1cd's Introduction

Tool 1CD

Полезный инструмент для работы с файлами 1CD за авторством Валерия Агеева с адаптацией от сообщества.

Что здесь происходит

В апреле 2017 года автор проекта Валерий Агеев поделился с сообществом исходными кодами проекта. Изначально проект был написан на Borland C++ Builder, здесь мы занимаемся переносом на "ванильный C++" с поддержкой компиляторов gcc, mingw и msvc и постепенным переходом на более свежие стандарты языка C++.

Установка

Проект в процессе разработки.

Последние тестовые сборки можно получать через публичные CI-сервера:

sudo add-apt-repository ppa:dmpas/e8
sudo apt-get update
sudo apt-get install ctool1cd

Сборка

см. BUILD.md

Использование

-l, -logfile <файл>

записывать все сообщения программы в текстовый лог-файл. Если файл существует, он перезаписывается. Кодировка файла UTF8

-ne, -NotExclusively

открыть базу не монопольно (Это небезопасно, возможны ошибки!).

-eax, -ExportAllToXML <путь>

экспортировать по указанному пути все таблицы в XML.

-ex, -ExportToXML <путь> <список>

экспортировать по указанному пути указанные таблицы в XML. В списке через запятую, точку с запятой или пробел указывается список имен экспортируемых таблиц. Можно использовать знаки подстановки * и ? Если в списке содержатся пробелы, список необходимо заключать в кавычки.

-bf, -BlobToFile [yes/no]

при экспорте в XML выгружать BLOB в отдельные файлы. По умолчанию BLOB в отдельные файлы не выгружается.

-pb, -ParseBlob [yes/no]

при экспорте в XML и выгрузке BLOB в отдельные файлы по-возможности распаковывать данные BLOB. По умолчанию BLOB при выгрузке в отдельные файлы распаковываются.

-dc, -DumpConfig <путь>

Выгрузить основную конфигурацию информационной базы по указанному пути.

-ddc, -DumpDBConfig <путь>

Выгрузить конфигурацию базы данных информационной базы по указанному пути.

-dvc, -DumpVendorsConfigs <путь>

Выгрузить конфигурации поставщиков информационной базы по указанному пути.

-dac, -DumpAllConfigs <путь>

Выгрузить все конфигурации информационной базы по указанному пути.

-drc, -DumpDepotConfig <номер версии> <путь>

Выгрузить конфигурацию хранилища заданной версии по указанному пути. Номер версии - это целое число. 1, 2, 3 и т.д. - выгрузить конфигурацию указанной версии, 0 - выгрузить последнюю версию, -1 - предпоследнюю и т.д.

-dpc, -DumpPartDepotConfig <номер версии>[:<номер версии>] <путь>

Выгрузить частично файлы конфигурации хранилища заданной версии (или заданного диапазона версий) по указанному пути. Номер версии - это целое число. 1, 2, 3 и т.д. - выгрузить файлы указанной версии, 0 - выгрузить файлы последней версии, -1 - предпоследней и т.д.

-eb, -ExportToBinary <путь> <список>

Экспортировать по указанному пути указанные таблицы. В списке через запятую, точку с запятой или пробел указывается список имён экспортируемых таблиц. Можно использовать знаки подстановки * и ? Если в списке содержатся пробелы, список необходимо заключать в кавычки.

-ib, -ImportFromBinary <путь> <список>

Импортировать по указанному пути указанные таблицы. В списке через запятую, точку с запятой или пробел указывается список имён импортируемых таблиц. Можно использовать знаки подстановки * и ? Если в списке содержатся пробелы, список необходимо заключать в кавычки. Таблицы должны существовать в базе, новые таблицы не создаются.

-slo, -SaveLostObjects <путь>

Найти потерянные объекты и сохранить.

Если в пути содержатся пробелы, его необходимо заключать в кавычки. Пути следует указывать без завершающего слеша / и бэкслеша \ Для команд -dc, -ddc, -drc вместо пути можно указывать имя файла конфигурации (имя файла должно заканчиваться на .cf).

tool1cd's People

Contributors

ava57r avatar awa15 avatar dmpas avatar fishca avatar fishca77 avatar levkinsergey avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tool1cd's Issues

Ошибка распаковки поля EXTDATA таблицы EXTERNALS при установленных параметрах ActionXMLSaveBLOBToFileChecked = true ActionXMLUnpackBLOBChecked = true

При распаковке таблицы EXTERNALS файла 1cv8ddb по ключу -eax
программа падает на строке

int64_t TMemoryStream::Read(void *Buffer, int64_t Count)
...
memcpy(Buffer, _data.data() + m_position, toRead);
...

Стэк
m_position = -1944278050
toRead = 1944286741

Список вызовов

int64_t TMemoryStream::Read(void *Buffer, int64_t Count)
TStream* read_block(TStream* stream_from, int start, TStream* stream_to = NULL)
void v8catalog::initialize()

Причина в этом куске кода

_fat = read_block(data, 16);
_fat->Seek(0, soFromBeginning);
_countfiles = _fat->GetSize() / 12;
for(int i = 0; i < _countfiles; i++){
	_fat->Read(&_fi, 12);
	read_block(data, _fi.header_start, _file_header);
	_file_header->Seek(0, soFromBeginning);
	_temp_buf = new char[_file_header->GetSize()];
	_file_header->Read(_temp_buf, _file_header->GetSize());
	_name = (WCHART*)(_temp_buf + 20);
	_file = new v8file(this, _name, _prev, _fi.data_start, _fi.header_start, (int64_t*)_temp_buf, (int64_t*)(_temp_buf + 8));
	delete[] _temp_buf;
	if(!_prev) first = _file;
	_prev = _file;
}

_fat->GetSize() = 24
countfiles = 2
Вот на второй итерации грохается.

Исправить hex_to_int(char* hexstr)

Проверяются только первые 8 байт, а при использовании передаются массивы до 20 байт

curlen = hex_to_int(&temp_buf[11]);
start  = hex_to_int(&temp_buf[20]);

тут вообще выход за границы массива получается.

len = hex_to_int(&temp_buf[2]);

Разобраться с наследованием в TableFileStream и TV8FileStream

Большинство методов этих классов указаны как virtual, но не все перепределяют методы базового класса (типы формальных параметров не совпадают).
Надо разобраться какие переопеределяют, а какие замещают

Неправильная обработка параметров командной строки (ParseBlob,BlobToFile)

При вызове команд
T1CD_cmd_export_all_to_xml
T1CD_cmd_export_to_xml

Производится анализ параметров

bool ActionXMLSaveBLOBToFileChecked = IsTrueString(pc.param1);
bool ActionXMLUnpackBLOBChecked     = IsTrueString(pc.param1);

Также данные параметры анализируются в функции main

case cmd_xml_blob_to_file:
	ActionXMLSaveBLOBToFileChecked = IsTrueString(pc.param1);
	break;
case cmd_xml_parse_blob:
	ActionXMLUnpackBLOBChecked = IsTrueString(pc.param1);
	break;

Получается 2 несвязанные проверки.

Реализовать класс TableRecord

Метод Table::getrecord возвращает указатель на массив char
Первый байт в массиве предположительно означает удалена запись или нет
\001 - delete
\0 - active

Необходим класс, чтобы скрыть это в реализации и не сравнивать каждый раз
if(*rec)
if(!*rec)
Например как тут:

rec = new char[t->get_recordlen()];
t->getrecord(nrec, rec);
if(*rec)

table_depot->getrecord(i, rec);
if(!*rec)

table_versions->getrecord(i, rec);
if(*rec) continue;

Плюс класс должен скрыть работу и владение массивом char (RAII)

Реализовать методы получения частей записи по offset как массив char - аля bytes(offset, len)

Оценить необходимость использования кода проверки наличия snapshot нужной версии конфигурации

Class_1CD.cpp

  // Проверяем, нет ли снэпшота нужной версии конфигурации 
  if(*(rec + fldv_snapshotcrc->offset)) if(*(rec + fldv_snapshotmaker->offset)) if(memcmp(rootobj, rec + fldv_snapshotmaker->offset + 1, 16) == 0) 
  { 
    _crc = *(uint32_t*)(rec + fldv_snapshotcrc->offset + 1); 
 
    //s = System.IOUtils.TPath::GetDirectoryName(filename); 
    s = filename.SubString(1, filename.LastDelimiter("\\")); 
    s += "cache\\ddb"; 
    ss = "00000"; 
    ss += ver; 
    s += ss.SubString(ss.GetLength() - 4, 5); 
    s += ".snp"; 
    if(FileExists(s)) 
    { 
      try 
      { 
        in = new TFileStream(s, fmOpenRead | fmShareDenyNone); 
      } 
      catch(...) 
      { 
        if(msreg) msreg->AddMessage_("Не удалось открыть файл снэпшота", msWarning, 
          "Имя файла", s, 
          "Требуемая версия", ver); 
        in = NULL; 
      } 
      try 
      { 
        //if(FileExists(__filename)) DeleteFile(__filename); 
        out = new TFileStream(__filename, fmCreate | fmShareDenyWrite); 
      } 
      catch(...) 
      { 
        if(msreg) msreg->AddMessage_("Не удалось создать файл конфигурации", msWarning, 
          "Имя файла", __filename); 
        delete[] rec; 
        return false; 
      } 
      if(in) 
      { 
        try 
        { 
          InflateStream(in, out); 
        } 
        catch(...) 
        { 
          if(msreg) msreg->AddMessage_("Не удалось распаковать файл снэпшота", msWarning, 
            "Имя файла", s, 
            "Требуемая версия", ver); 
          delete out; 
          out = NULL; 
        } 
        delete in; 
        in = NULL; 
        if(out) 
        { 
          k = _crc32(out); 
          if(k == _crc) 
          { 
            delete out; 
            delete[] rec; 
            return true; 
          } 
          if(msreg) msreg->AddMessage_("Файл снэпшота испорчен (не совпала контрольная сумма)", msWarning, 
            "Имя файла", s, 
            "Требуемая версия", ver, 
            "Должен быть CRC32", tohex(_crc), 
            "Получился CRC32", tohex(k)); 
          delete out; 
        } 
      } 
    } 
    else 
    { 
      if(msreg) msreg->AddMessage_("Не найден файл снэпшота", msWarning, 
        "Имя файла", s, 
        "Требуемая версия", ver); 
    } 
  } 

Изменить код использующий ZInflateStream

Использование ZInflateStream обрамляется в try блоки, но данная функция не генерирует исключений и код, который ее использует подобным образом работает не правильно.

Сделать help в стиле man страниц

Предлагаю сделать help по примеру man страниц.

-a, --append
           Добавить пользователя в дополнительную группу(ы). Использовать только вместе с параметром -G.

Сокрощенный вариант и полный в одну строку через запятую.
Так же можно и man-страницу саму сделать.

Исправить предупреждения при сборке x64-Linux

SystemClasses/TMemoryStream.cpp|32|предупреждение: сравнение знакового и беззнакового целых выражений [-Wsign-compare]|
SystemClasses/TStream.cpp|83|предупреждение: сравнение знакового и беззнакового целых выражений [-Wsign-compare]|

Заготовки для тестов

В каталоге tests есть хранилища depot*/depot. Нужно для каждого из них отдельным файлом создать шаблон теста. В шаблоне должно быть только открытие файла хранилища.

Создать класс для работы с датой

dmpas commented an hour ago

@andreevlex
вынеси работу с датой в отдельный класс, в нём же заведи константу. Переименуй константу 7fff, пространства имён пока оставь.

#35

Экранировать имена файлов BLOB-ов

Для регистров сведений имя файла BLOB поля содержит в себе значения измерений. Соответственно, там могут быть символы, недопустимые в имени файла.

Необходимо продумать, как сохранять такие BLOB-ы

Ошибка выгрузки конфигурации из хранилища версии 6 по ключу -DumpPartDepotConfig

Чтение таблиц 0
Чтение таблиц 10
База данных 1CD открыта
	Файл = /home/ubuntu/dev-pro/testctool1cd/InfoBase2/1cv8ddb.1CD
	Версия базы = 8.2.14.0
	Locale = ru_RU
	Режим = Редактирование
	Количество таблиц = 10
Чтение индекса 

Чтение индекса 

Чтение индекса 

Не найден файл
	Файл = data\objects\da927bd252f71b5d9ed8ed3619948a54be4445353b
	Таблица = HISTORY
	Объект = 9c506306-dd76-4c36-9930-5eafba54e3ac
	Версия = 2
Ошибка чтения объекта конфигурации
	Таблица = HISTORY
	Объект = 9c506306-dd76-4c36-9930-5eafba54e3ac
	Версия = 2
Не найден файл
	Файл = data\objects\ba923fe4e4f882908c8e7c723678eb8595233fdd26
	Таблица = HISTORY
	Объект = e9c79ae8-b5ea-43d7-8ed9-727a784407ac
	Версия = 2
Ошибка чтения объекта конфигурации
	Таблица = HISTORY
	Объект = e9c79ae8-b5ea-43d7-8ed9-727a784407ac
	Версия = 2
Сохранение файлов конфигурации хранилища завершено.
	Файл = /home/ubuntu/dev-pro/testctool1cd/InfoBase2

Неявное приведение типов размера данных при распаковке

Как-то все это выглядет не правильно
srcSize - типа uintmax_t
src->GetSize() возвращает тип int64_t
src->Read(srcBuf, srcSize) принимает 2-м параметром тип int64_t

ctool1cd/UZLib.cpp

void ZInflateStream(TStream* src, TStream* dst)
{
	...
	uintmax_t srcSize;
...
		srcSize = src->GetSize();         // определяем размер данных
		src->Read(srcBuf, srcSize);  // читаем из потока в буфер данные
strm.avail_in = srcSize;

Избавиться от define в файлах (h, cpp)

Заменить define определения литералов на константы
Макро-функции заменить на функции
Для общих констант определить общий заголовочный файл

Ошибка выгрузки конфигурации из хранилища версии 7 по ключу -drc

  1 Чтение таблиц 0
  2 Чтение таблиц 10
  3 База данных 1CD открыта
  4   Файл = /home/ubuntu/dev-pro/testctool1cd/хранилище/1cv8ddb.1CD
  5   Версия базы = 8.3.8.0
  6   Locale = ru_RU
  7   Режим = Редактирование
  8   Количество таблиц = 10
  9 Чтение индекса
 10 
 11 Чтение индекса
 12 
 13 Чтение индекса
 14 
 15 Не найден файл
 16   Файл = /home/ubuntu/dev-pro/testctool1cd/хранилище/1cv8ddb.1CD/data/objects/d77c497e1adcf0d71d0daeb2dad35a43c2b7a6
 17   Таблица = HISTORY
 18   Объект = 9f805d9a-70bf-474b-9b1f-ca1fc5b9839b
 19   Версия = 2
 20 Ошибка чтения объекта конфигурации
 21   Таблица = HISTORY
 22   Объект = 9f805d9a-70bf-474b-9b1f-ca1fc5b9839b
 23   Версия = 2
 24 Сохранение конфигурации хранилища завершено.
 25   Файл = /home/ubuntu/dev-pro/testctool1cd/1cvbddb_dep/v2.cf

depot_ver7.zip

Выгрузка blob

19_06
Из-за этого изменения выгрузка
19_06_1
формируется неправильно.

TODO: Tasks list

Text Type Path
0x3ff000 в константу TODO src/tool1cd/V8Object.cpp
10МиБ в константу TODO src/tool1cd/Class_1CD.cpp
31 в константу TODO src/tool1cd/cfapi/V8Catalog.cpp
адовый костыль с утечкой памяти TODO src/tool1cd/FieldType.cpp
адовый костыль с утечкой памяти TODO src/tool1cd/FieldType.cpp
адовый костыль с утечкой памяти TODO src/tool1cd/FieldType.cpp
блокировка на memblocks TODO src/tool1cd/MemBlock.cpp
бросить исключение??? TODO src/tool1cd/ConfigStorage.cpp
бросить исключение??? TODO src/tool1cd/ConfigStorage.cpp
бросить исключение??? TODO src/tool1cd/ConfigStorage.cpp
бросить исключение??? TODO src/tool1cd/ConfigStorage.cpp
Вероятно, это теперь лишнее TODO src/SystemClasses/System.SysUtils.cpp
Вменяемое сравнение в соответствии с типами TODO src/tool1cd/Table.cpp
Возвращаемое значение TableFileStream::Read(void *Buffer, int32_t Count) TODO src/tool1cd/TableFileStream.cpp
Впилить толковые строки TODO src/SystemClasses/String.cpp
Впилить толковые строки TODO src/SystemClasses/String.cpp
выпилен кусок кода TODO src/tool1cd/Class_1CD.cpp
Действительно ли тут ошибка?? и с такой ли формулировкой?? TODO src/tool1cd/Table.cpp
заменить на что-нибудь вроде add_free_block TODO src/tool1cd/V8Object.cpp
Запись в таблицы пока не поддерживается TODO src/tool1cd/ConfigStorage.cpp
инициализация null_index TODO src/tool1cd/FieldType.cpp
Исправить работу TEncoding::Convert TODO src/SystemClasses/System.SysUtils.cpp
как это работает? TODO src/tool1cd/cfapi/V8Catalog.cpp
кодировка TEncoding::Convert() TODO src/SystemClasses/TStreamWriter.cpp
константы 20, 8 TODO src/tool1cd/cfapi/V8Catalog.cpp
критичная ошибка? Обработка на месте? TODO src/tool1cd/SupplierConfigBuilder.cpp
Мудрое название TODO src/tool1cd/BinaryGuid.h
Надо доделать для showGUIDasMS TODO src/tool1cd/FieldType.cpp
не забыть про сей костыль TODO src/tool1cd/Table.cpp
не забыть про сей костыль TODO src/tool1cd/Table.cpp
Ошибка! Имя файла базы уже было в командной строке! TODO src/ctool1cd/ParseCommandLine.cpp
Ошибка! Недостаточно параметров ключа! TODO src/ctool1cd/ParseCommandLine.cpp
Ошибка! Неизвестный ключ! TODO src/ctool1cd/ParseCommandLine.cpp
Перенести логику сюда TODO src/tool1cd/BinaryGuid.cpp
Полечить дичайшие утечки памяти TODO src/tool1cd/save_depot_config.cpp
проверить, надо ли номера свободных страниц преобразовывать в смещения для версий от 8.0 до 8.2.14 TODO src/tool1cd/Index.cpp
работа с pagesize TODO src/tool1cd/Class_1CD.cpp
работа с pagesize TODO src/tool1cd/Class_1CD.cpp
работа с pagesize TODO src/tool1cd/Class_1CD.cpp
работа с pagesize TODO src/tool1cd/Class_1CD.cpp
работа с pagesize TODO src/tool1cd/Class_1CD.cpp
работа с pagesize TODO src/tool1cd/Class_1CD.cpp
разобраться LAST_PAGE == UINT_MAX, а тут uint64_t curblock FIXME src/tool1cd/Index.cpp
разобраться, зачем обнуляется указатель TODO src/tool1cd/cfapi/V8File.cpp
реализовать кроссплатформенное преобразование локального системного файлового времени в универсальное (UTC) файловое ... TODO src/SystemClasses/System.cpp
реализовать TableFileStream::Read(System::DynamicArraySystem::t::Byte Buffer, int32_t Offset, int32_t Count) TODO src/tool1cd/TableFileStream.cpp
реализовать TableFileStream::Seek(const int64_t Offset, TSeekOrigin Origin) TODO src/tool1cd/TableFileStream.cpp
реализовать TableFileStream::Seek(int32_t Offset, System::Word Origin) TODO src/tool1cd/TableFileStream.cpp
реализовать TStream::SetSize TODO src/SystemClasses/TStream.cpp
реализовать V8Object::get_fileoffset для файла свободных страниц формата 8.3.8 TODO src/tool1cd/V8Object.cpp
реализовать V8Object::getdata для файла свободных страниц формата 8.3.8 TODO src/tool1cd/V8Object.cpp
реализовать V8Object::getdata() для файла свободных страниц формата 8.3.8 TODO src/tool1cd/V8Object.cpp
ругнуться TODO src/gtool1cd/models/table_data_model.cpp
сообщить об ошибке и записать в log TODO src/tool1cd/ConfigStorage.cpp
тип под Datahash TODO src/tool1cd/save_part_depot_config.cpp
тут должно быть что-то иное TODO src/tool1cd/Table.cpp
тут должны быть уник_птр TODO src/tool1cd/MemBlock.h
убрать это куда-нибудь TODO src/tool1cd/FieldType.h
убрать mutable TODO src/tool1cd/Index.h
убрать mutable TODO src/tool1cd/Index.h
утечка данных TODO src/tool1cd/TableRecord.cpp
AddDebugMessage TODO src/tool1cd/MessageRegistration.cpp
Any general catch headers included here must be included NB src/tests/catch.hpp
Check testGroupStats.aborting and act accordingly. TODO src/tests/catch.hpp
It's a bit ugly, but it works NOTE src/gtool1cd/QHexEdit/paint/qhexpainter.cpp
StartIndex, Count TODO src/SystemClasses/System.SysUtils.cpp
wat?? TODO src/tool1cd/Class_1CD.cpp
ZDeflateStream проверка ошибок TODO src/tool1cd/UZLib.cpp

Модульные тесты

Допилка с датой навела на мысль, что "пора". Пора покрывать модульными тестами подобный функционал, который глазом не проверить.

Накидывайте сюда ссылок на всякие тестовые движки для плюсов, будем выбирать подходящий.

/cc @fishca @andreevlex

Тесты

@artbear ты обещал тесты :) есть мысли, как тестить?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.