diff --git a/pyOneNote/FileNode.py b/pyOneNote/FileNode.py index a5f04d0..c9368a3 100644 --- a/pyOneNote/FileNode.py +++ b/pyOneNote/FileNode.py @@ -143,10 +143,27 @@ def __init__(self, file, document): file.seek(self.data.ref.stp) self.propertySet = ObjectSpaceObjectPropSet(file, document) file.seek(current_offset) + elif self.file_node_header.file_node_type == "ObjectDeclaration2LargeRefCountFND": + self.data = ObjectDeclaration2LargeRefCountFND(file, self.document, self.file_node_header) + current_offset = file.tell() + if self.data.body.jcid.IsPropertySet: + file.seek(self.data.ref.stp) + self.propertySet = ObjectSpaceObjectPropSet(file, document) + file.seek(current_offset) elif self.file_node_header.file_node_type == "ReadOnlyObjectDeclaration2LargeRefCountFND": self.data = ReadOnlyObjectDeclaration2LargeRefCountFND(file, self.document, self.file_node_header) + current_offset = file.tell() + if self.data.base.body.jcid.IsPropertySet: + file.seek(self.data.base.ref.stp) + self.propertySet = ObjectSpaceObjectPropSet(file, document) + file.seek(current_offset) elif self.file_node_header.file_node_type == "ReadOnlyObjectDeclaration2RefCountFND": self.data = ReadOnlyObjectDeclaration2RefCountFND(file, self.document, self.file_node_header) + current_offset = file.tell() + if self.data.base.body.jcid.IsPropertySet: + file.seek(self.data.base.ref.stp) + self.propertySet = ObjectSpaceObjectPropSet(file, document) + file.seek(current_offset) elif self.file_node_header.file_node_type == "FileDataStoreListReferenceFND": self.data = FileDataStoreListReferenceFND(file, self.file_node_header) elif self.file_node_header.file_node_type == "FileDataStoreObjectReferenceFND": @@ -174,10 +191,10 @@ def __init__(self, file, document): # no data part self.data = None else: - p = 1 + self.data = None current_offset = file.tell() - if self.file_node_header.baseType == 2: + if self.file_node_header.baseType == 2 and self.data is not None: self.children.append(FileNodeList(file, self.document, self.data.ref)) file.seek(current_offset) @@ -638,9 +655,19 @@ def __init__(self, file, OIDs, OSIDs, ContextIDs, document): count, = struct.unpack(' 0 a prid PropertyID + # (4 bytes, always type 0x11/PropertySet) followed by that + # many nested PropertySet structures. + count, = struct.unpack(' 0: + PropertyID(file) # prid header, type is always 0x11 here + for _ in range(count): + array_data.append(PropertySet(file, OIDs, OSIDs, ContextIDs, document)) + self.rgData.append(array_data) elif type == 0x11: - self.rgData.append(PropertySet(file)) + self.rgData.append(PropertySet(file, OIDs, OSIDs, ContextIDs, document)) else: raise ValueError('rgPrids[i].type is not valid') @@ -664,6 +691,12 @@ def get_properties(self): if isinstance(self.rgData[i], PrtFourBytesOfLengthFollowedByData): if 'guid' in propertyName.lower(): propertyVal = uuid.UUID(bytes_le=self.rgData[i].Data).hex + elif propertyName == 'TextExtendedAscii': + # OneNote for Mac stores plain-text runs as single-byte + # (latin-1) text under this property, instead of the + # UTF-16 RichEditTextUnicode Windows OneNote uses. + # Decoding it as utf-16 either garbles it or throws. + propertyVal = self.rgData[i].Data.decode('latin-1') else: try: propertyVal = self.rgData[i].Data.decode('utf-16') diff --git a/pyOneNote/OneDocument.py b/pyOneNote/OneDocument.py index 906a606..fcccd5d 100644 --- a/pyOneNote/OneDocument.py +++ b/pyOneNote/OneDocument.py @@ -24,7 +24,18 @@ def get_properties(self): if self._properties: return self._properties nodes = [] - filters = ['ObjectDeclaration2RefCountFND'] + # ObjectDeclaration2LargeRefCountFND is used for objects whose + # reference count doesn't fit in one byte (e.g. more heavily-shared + # or larger page content), and the ReadOnly* variants wrap either + # declaration with an extra md5Hash. All four carry the same + # propertySet-bearing body and were previously excluded here, which + # silently dropped any text stored under them. + filters = [ + 'ObjectDeclaration2RefCountFND', + 'ObjectDeclaration2LargeRefCountFND', + 'ReadOnlyObjectDeclaration2RefCountFND', + 'ReadOnlyObjectDeclaration2LargeRefCountFND', + ] self._properties = [] @@ -32,7 +43,9 @@ def get_properties(self): for node in nodes: if hasattr(node, 'propertySet'): node.propertySet.body.indent= '\t\t' - self._properties.append({'type': str(node.data.body.jcid), 'identity':str(node.data.body.oid), 'val':node.propertySet.body.get_properties()}) + # ReadOnly* variants wrap the declaration in `.base`. + decl_body = node.data.base.body if hasattr(node.data, 'base') else node.data.body + self._properties.append({'type': str(decl_body.jcid), 'identity':str(decl_body.oid), 'val':node.propertySet.body.get_properties()}) return self._properties