Sprawdzanie plików typu „NeXT / Apple typedstream” wersja 4 (NSArchiver)

W przypadku programu do odzyskiwania danych muszę być w stanie wyodrębnić wartości + typy z plików napisanych przez NSArchiver, bez dostępu do struktur CF / NS firmy Apple.

OS Xfile polecenie zgłasza takie pliki jak:

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

Czy jest jakaś dokumentacja dotycząca sposobu kodowania tych plików lub czy ktoś wymyślił kod, który może je przeanalizować?

Oto przykład takich danych (również:do pobrania):

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                                   .....

Zawiera ciąg NSAttributesString. Mam podobne przykłady, które zawierają NSMutableAttributedStrings itp., Ale ostatecznie rozwiązują się w NSAttributedStrings, dla których lubię pobierać tekst. Nie dbam o resztę, ale muszę wiedzieć, czy to ważne.

Moim obecnym rozwiązaniem jest użycie NSUnarchiver i zakładając, że zawsze znajdę tam NSAttributedString, pobierz jego pierwszy element i przeczytaj jego tekst, a następnie utwórz z niego archiwum i sprawdź, czy jest ono takie samo jak oryginalne dane. Jeśli otrzymam wyjątek lub inne archiwum, zakładam, że archiwum jest uszkodzone lub nieprawidłowe:

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
}

Istnieje jednak kilka problemów z powyższym kodem:

To nie jest platforma x. Potrzebuję tego również do pracy w systemie Windows.Niektóre przykłady uszkodzonych danych powodują niepożądane komunikaty o błędach zapisane na stderr lub syslog (nie wiem, które), takie jak:*** mmap(size=18446744071608111104) failed (error code=12) *** error: can't allocate region *** set a breakpoint in malloc_error_break to debug (Niestety niestety złożyłem raport o błędzie dotyczący tego, który został zamknięty jako „nie naprawi”).Nic nie gwarantuje, że kod NSUnarchiver jest w 100% odporny na awarie. Przykładem może być błąd malloc. Równie dobrze mógłbym dostać błąd autobusu w niektórych sytuacjach, a to byłoby śmiertelne. Gdybym miał niestandardowy kod do parsowania, mogę sam się tym zająć (i naprawić wszelkie awarie, które napotykam). (Aktualizacja: Właśnie znalazłem nieprawidłowe dane, które rzeczywiście powodują awarię NSUnarchiver za pomocą SIGSEGV).

Dlatego potrzebuję niestandardowego kodu do dekodowania tego rodzaju archiwów. Spojrzałem na kilka, ale nie rozumiem kodów, których używa. Najwyraźniej istnieją pola długości i pola typu, przy czym typy są w zakresie około 0x81 do 0x86. Ponadto pierwsze 16 bajtów to nagłówek, w tym kod systemowy (0x03E8 = 1000) przy przesunięciu 14-15.

Zastanawiam się również, czy kod źródłowy jest dostępny w niektórych starych źródłach NeXT lub w wersji Windows, która kiedyś istniała, ale gdzie znajdę to? (Uwaga: zostałem skierowany do źródła GNUstep ("core.20131003.tar.bz2"), w którym znalazłem jego źródło NSUnarchiver, ale ten kod, najwyraźniej z 1998 r., Używa własnego kodowania, które nie rozumie tego „kodowanie.)

questionAnswers(6)

yourAnswerToTheQuestion