Проверка файлов типа «NeXT / Apple typedstream» версия 4 (NSArchiver)

Для программы восстановления данных мне нужно иметь возможность извлекать значения + типы из файлов, написанных NSArchiver, без доступа к Apple 's CF / NS рамки.

OS Xfile команда сообщает такие файлы как:

NeXT/Apple typedstream data, little endian, version 4, system 1000

Есть ли документация о том, как эти файлы кодируются, или кто-нибудь придумал код, который может их проанализировать?

Вот's пример таких данных (также:загружаемое):

04 0B 73 74 72 65 61 6D 74 79 70 65 64 81 E8 03  ..streamtyped...
84 01 40 84 84 84 12 4E 53 41 74 74 72 69 62 75  [email protected]
74 65 64 53 74 72 69 6E 67 00 84 84 08 4E 53 4F  tedString....NSO
62 6A 65 63 74 00 85 92 84 84 84 08 4E 53 53 74  bject.......NSSt
72 69 6E 67 01 94 84 01 2B 06 46 65 73 6B 65 72  ring....+.Fesker
86 84 02 69 49 01 06 92 84 84 84 0C 4E 53 44 69  ...iI.......NSDi
63 74 69 6F 6E 61 72 79 00 94 84 01 69 01 92 84  ctionary....i...
96 96 1D 5F 5F 6B 49 4D 4D 65 73 73 61 67 65 50  ...__kIMMessageP
61 72 74 41 74 74 72 69 62 75 74 65 4E 61 6D 65  artAttributeName
86 92 84 84 84 08 4E 53 4E 75 6D 62 65 72 00 84  ......NSNumber..
84 07 4E 53 56 61 6C 75 65 00 94 84 01 2A 84 99  ..NSValue....*..
99 00 86 86 86                                   .....

Это содержит NSAttributedString. У меня есть похожие примеры, которые содержат NSMutableAttributedStrings и т. Д., Но все в конечном итоге разрешаются в NSAttributedStrings, для которых мне нравится получать текст. Мне все равно, но мне нужно знать,действительно.

Мое текущее решение состоит в том, чтобы использовать NSUnarchiver и, предполагая, что я всегда должен найти там NSAttributedString, получить его первый элемент и прочитать его текст, а затем заново создать из него архив и посмотреть, совпадает ли он с исходными данными. Если я получу исключение или другой архив обратно, я предполагаю, что архив поврежден или недействителен:

NSData *data = [[NSData alloc] initWithBytesNoCopy:dataPtr length:dataLen freeWhenDone:false];
NSUnarchiver *a = NULL;

// The algorithm simply assumes that the data contains a NSAttributedString, retrieves it,
// and then recreates the NSArchived version from it in order to tell its size.
@try {
    a = [[NSUnarchiver alloc] initForReadingWithData:data];
    NSAttributedString *s = [a decodeObject];

    // re-encode the string item so we can tell its length
    NSData *d = [NSArchiver archivedDataWithRootObject:s];
    if ([d isEqualTo:[data subdataWithRange:NSMakeRange(0,d.length)]]) {
        lenOut = (int) d.length;
        okay = true; // -> lenOut is valid, though textOut might still fail, see @catch below
        textOut = [s.string cStringUsingEncoding:NSUTF8StringEncoding];
    } else {
        // oops, we don't get back what we had as input, so let's better not consider this valid
    }
} @catch (NSException *e) {
    // data is invalid
}

Однако есть несколько проблем с приведенным выше кодом:

Это'не х-платформа. Мне нужно, чтобы это тоже работало в Windows.Некоторые примеры поврежденных данных приводят к нежелательной ошибке msg, записанной в stderr или syslog (не знаю, какой), например:*** mmap(size=18446744071608111104) failed (error code=12) *** error: can't allocate region *** set a breakpoint in malloc_error_break to debug (Я подал отчет об ошибке, который был закрыт как "победил'т исправить "К сожалению)Ничто не гарантирует, что код NSUnarchiver на 100% защищен от сбоев. Ошибка malloc является примером для этого. Я мог бы также получить ошибку шины в некоторых ситуациях, и это 'был бы смертельным. Если бы у меня был собственный код для разбора, я мог бы сам позаботиться об этом (и исправить любые сбои, с которыми я столкнулся). (Обновление: я только что нашел недопустимые данные, которые действительно приводят к сбою NSUnarchiver с SIGSEGV.)

Поэтому мне нужен собственный код для декодирования таких архивов. Я'Я посмотрел на несколько, но могуне имеет смысла коды, которые он использует. По-видимому, существуют поля длины и поля типов, причем типы находятся в диапазоне от 0x81 до 0x86, по-видимому. Кроме того, первые 16 байтов являются заголовком, включая системный код (0x03E8 = 1000) со смещением 14-15.

Мне также интересно, доступен ли исходный код в некоторых старых исходниках NeXT или в версии для Windows, которая когда-то существовала, но где я могу найти это? (Примечание: я был направлен на источник GNUstep ("core.20131003.tar.bz2"), в котором я нашел его исходный код NSUnarchiver, но этот код, по-видимому, с 1998 года, использует свою собственную кодировку, которая не 'не понимаю это "streamtyped» кодирование.)

Ответы на вопрос(6)

Ваш ответ на вопрос