Skip to content

Implement ArrayOfPropertyValues + fix nested PropertySet, unknown FileNode, and TextExtendedAscii decode#33

Open
Thenewmanator15 wants to merge 1 commit into
DissectMalware:mainfrom
Thenewmanator15:fix-arrayofpropertyvalues-and-text-decode
Open

Implement ArrayOfPropertyValues + fix nested PropertySet, unknown FileNode, and TextExtendedAscii decode#33
Thenewmanator15 wants to merge 1 commit into
DissectMalware:mainfrom
Thenewmanator15:fix-arrayofpropertyvalues-and-text-decode

Conversation

@Thenewmanator15

Copy link
Copy Markdown

What

Four fixes that let real OneNote .one sections parse end-to-end instead of crashing partway through PropertySet/FileNode parsing.

1. PropertySet type 0x10 (ArrayOfPropertyValues) — was NotImplementedError

The hard blocker. Implemented per [MS-ONESTORE] §2.6.9: a uint32 count, then (only when count > 0) one prototype PropertyID, then count PropertySet structures, drawing ObjectIDs from the parent's OID/OSID/ContextID streams.

2. PropertySet type 0x11 (nested PropertySet) — wrong arg count

self.rgData.append(PropertySet(file)) would raise TypeError the moment a nested property set was reached (__init__ needs file, OIDs, OSIDs, ContextIDs, document). Now passes the parent streams like every other call site.

3. FileNode: unrecognised FileNodeID → AttributeError

An unknown FileNodeID fell through to else: p = 1 without setting self.data, then the baseType == 2 branch dereferenced self.data.ref. Now sets self.data = None and guards the child-list recursion on a present .ref.

4. get_properties: TextExtendedAscii mis-decoded

The single-byte TextExtendedAscii property was decoded as UTF-16, turning ASCII into CJK (e.g. Hypothesis祈潰桴獥獩) and, on odd byte lengths, silently falling back to raw hex. Now decodes TextExtendedAscii as cp1252 and the Unicode text property as utf-16-le.

Impact

On a real 60-page notebook this goes from an early crash to a full parse — 15,477 property nodes, all pages, embedded files recovered, and readable text. Fixes 1–3 are structural (parse completes); fix 4 makes the extracted text usable.

Notes

Changes are confined to pyOneNote/FileNode.py. The ArrayOfPropertyValues layout follows the count-then-prototype-then-N-PropertySets structure in [MS-ONESTORE] §2.6.9; verified against a notebook whose node-type histogram (thousands of ObjectDeclaration2RefCountFND, correct page/title/table/list counts) confirms correct stream alignment.

…eNode, and text decode

Four fixes that let real OneNote (.one) sections parse end-to-end instead of
crashing:

1. PropertySet type 0x10 (ArrayOfPropertyValues) was `raise NotImplementedError`.
   Implemented per [MS-ONESTORE] 2.6.9: a uint32 count, then (only when count>0)
   one prototype PropertyID, then `count` PropertySet structures.

2. PropertySet type 0x11 (nested PropertySet) called `PropertySet(file)` with the
   wrong arg count and would raise TypeError as soon as it was reached. It now
   passes the parent OID/OSID/ContextID streams and document, like every other site.

3. FileNode: an unrecognised FileNodeID fell through to `else: p = 1` without
   setting `self.data`, then the `baseType == 2` branch dereferenced
   `self.data.ref` -> AttributeError. Set `self.data = None` and guard the
   child-list recursion on a present `.ref`.

4. get_properties decoded the single-byte TextExtendedAscii property as UTF-16,
   turning ASCII text into CJK and (on odd lengths) falling back to raw hex.
   Decode TextExtendedAscii as cp1252 and the Unicode text as utf-16-le.

With these, a 60-page notebook parses fully (15477 property nodes, embedded files
recovered) and text comes out readable.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant