Skip to content

Commit

Permalink
darwin: add datetime serialization support
Browse files Browse the repository at this point in the history
  • Loading branch information
doronz88 committed Feb 28, 2022
1 parent 6946c0a commit a6d4213
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 4 deletions.
16 changes: 15 additions & 1 deletion src/rpcclient/rpcclient/darwin/client.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import datetime
import struct
import typing
from collections import namedtuple
Expand Down Expand Up @@ -101,7 +102,20 @@ def cf(self, o: object):
return self.symbols.CFStringCreateWithCString(kCFAllocatorDefault, o,
CFStringEncoding.kCFStringEncodingMacRoman)
elif isinstance(o, bytes):
return self.symbols.CFDataCreate(0, o, len(o))
return self.symbols.CFDataCreate(kCFAllocatorDefault, o, len(o))
elif isinstance(o, datetime.datetime):
comps = self.symbols.objc_getClass('NSDateComponents').objc_call('new')
comps.objc_call('setDay:', o.day)
comps.objc_call('setMonth:', o.month)
comps.objc_call('setYear:', o.year)
comps.objc_call('setHour:', o.hour)
comps.objc_call('setMinute:', o.minute)
comps.objc_call('setSecond:', o.second)
comps.objc_call('setTimeZone:',
self.symbols.objc_getClass('NSTimeZone').objc_call('timeZoneWithAbbreviation:',
self.cf('UTC')))
return self.symbols.objc_getClass('NSCalendar').objc_call('currentCalendar') \
.objc_call('dateFromComponents:', comps)
elif isinstance(o, bool):
if o:
return self.symbols.kCFBooleanTrue[0]
Expand Down
6 changes: 3 additions & 3 deletions src/rpcclient/rpcclient/darwin/symbol.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import datetime
import struct
import time
from typing import List, Mapping

from rpcclient.darwin.consts import kCFNumberSInt64Type, kCFNumberDoubleType, CFStringEncoding
Expand Down Expand Up @@ -52,8 +52,8 @@ def _decode_cfnumber(self) -> int:
raise CfSerializationError(f'failed to deserialize int: {self}')
return int(buf[0])

def _decode_cfdate(self) -> time.struct_time:
return time.strptime(self.cfdesc, '%Y-%m-%d %H:%M:%S %z')
def _decode_cfdate(self) -> datetime.datetime:
return datetime.datetime.strptime(self.cfdesc, '%Y-%m-%d %H:%M:%S %z')

def _decode_cfdata(self) -> bytes:
count = self._client.symbols.CFDataGetLength(self)
Expand Down
2 changes: 2 additions & 0 deletions src/rpcclient/tests/test_core_foundation_types.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import datetime
import pytest


@pytest.mark.parametrize('data', [
None,
True,
False,
datetime.datetime(1967, 5, 4, 3, 2, 1, tzinfo=datetime.timezone.utc),
'string',
b'bytes',
123,
Expand Down

0 comments on commit a6d4213

Please sign in to comment.