Re: [Toybox] Stat %Z - What are valid values?

2017-02-08 Thread Rob Landley
I still have this todo item:

On 12/30/2016 11:28 AM, darken wrote:
> I've seen a value of "18446744072363093454" for stat %Z (seconds since
> epoch), for some files on a users device (Android 6.01).

To which Elliot replied with:

On 12/30/2016 01:39 PM, enh wrote:
> time_t on 32-bit Android is 32 bits.
> 
> that particular value looks like a sign-extension of 0xAFBEADCE, which
> is still some time in 2063. (so i'd assume this device's clock is set
> wrong, and i'd assume -- since this is presumably a 32-bit device with
> a signed 32-bit time_t -- that that's going to be causing other
> problems too.)

Then I said:

> Or if it's signed, that's -1346458162 which would be... sometime in the
> 1930's? hmmm... "./date -D %s -d -1346458162" is failing under glibc,
> and failing _differently_ under musl. (Wheee.)

At which point I got distracted going off on a tangent instead of just
using "touch -d".

Years ago Linus ruled ex cathedra that time_t is gonna stay signed on
Linux (because otherwise you can't represent times before Jan 1 1970,
which a lot of people's birthdays still are):

  https://lkml.org/lkml/2011/8/31/246

Which means a 32 bit time_t has the year 2038 problem (and x32 needs a
64 bit time_t to stay relevant).

The problem here _isn't_ about casting time_t to unsigned, because it
isn't an unsigned value. (And unsigned 64 bit value still couldn't
represent times before 1970: it has to _remain_ signed after being
promoted to 64 bits or it's broken.)

That's why I didn't apply Elliott's patch with the sizeof() and typecast
staircase: I don't see how it can be the proper fix to the reported problem:

> with 64-bit toybox:
> 
> angler:/ # date 06022064

That date is past 2038...

> Mon Jun  2 00:00:00 GMT 2064
> angler:/ # rm /data/local/tmp/empty
> angler:/ # touch /data/local/tmp/empty
> angler:/ # ls -l /data/local/tmp/empty
> -rw-rw-rw- 1 root root 0 2064-06-02 00:00 /data/local/tmp/empty
> angler:/ # stat /data/local/tmp/empty
>   File: `/data/local/tmp/empty'
>   Size: 0 Blocks: 0 IO Blocks: 512 regular empty file
> Device: fd00h/64768d Inode: 3014659 Links: 1
> Access: (666/-rw-rw-rw-) Uid: (0/root) Gid: (0/root)
> Access: 2064-06-02 00:00:11.746667836
> Modify: 2064-06-02 00:00:11.746667836
> Change: 2064-06-02 00:00:11.746667836
> angler:/ # stat -c "%z %Z" /data/local/tmp/empty
> 2064-06-02 00:00:11.746667836 2979590411
> angler:/ # ^D

A 64 bit platform can represent that but a 32 bit one can't, because
it's past y2038.

> then with 32-bit toybox:
> 
> angler:/ # ls -l /data/local/tmp/empty
> -rw-rw-rw- 1 root root 0 1928-04-26 17:31 /data/local/tmp/empty

Because time_t is a 32 bit signed value there, so that bit pattern
represents a negative number.

> angler:/ # stat /data/local/tmp/empty
>   File: `/data/local/tmp/empty'
>   Size: 0 Blocks: 0 IO Blocks: 512 regular empty file
> Device: fd00h/64768d Inode: 3014659 Links: 1
> Access: (666/-rw-rw-rw-) Uid: (0/root) Gid: (0/root)
> Access: 1928-04-26 17:31:55.746667836
> Modify: 1928-04-26 17:31:55.746667836
> Change: 1928-04-26 17:31:55.746667836
> angler:/ # stat -c "%z %Z" /data/local/tmp/empty
> 1928-04-26 17:31:55.746667836 18446744072394174731

Why is "stat" showing the same data as "ls" a bad thing here? Your patch
to stat makes it diverge from ls? On a local i686-musl build:

/ # touch -d 1928-04-26T00:00:00 walrus
/ # ls -l walrus
-rw-r--r-- 1 root root 0 1928-04-26 00:00 walrus
/ # stat walrus
  File: `walrus'
  Size: 0Blocks: 0   IO Blocks: 512 regular empty file
Device: 801h/2049d   Inode: 14574425 Links: 1
Access: (644/-rw-r--r--)   Uid: (0/root)   Gid: (0/root)
Access: 1928-04-26 00:00:00.0
Modify: 1928-04-26 00:00:00.0
Change: 2017-02-08 20:58:37.009291677
/ #

> two patches attached. one avoids sign extension for all calls to
> `out`, fixing %Z for systems with a signed 32-bit time_t.

What does this patch fix?

Rob
___
Toybox mailing list
Toybox@lists.landley.net
http://lists.landley.net/listinfo.cgi/toybox-landley.net


Re: [Toybox] Stat %Z - What are valid values?

2017-01-26 Thread Rob Landley
On 01/25/2017 06:25 PM, Rich Felker wrote:
>> According to man 2 time:
>>
>>  time()  returns  the  time  as  the  number of seconds since the Epoch,
>>  1970-01-01 00:00:00 + (UTC).
>>
>> I.E. the definition of unix time is UTC. So %s _not_ being UTC is silly.
> 
> Nobody is questioning whether the input read by %s is UTC. The
> question is whether the output struct tm is UTC or local.
> 
>> My use case (and presumably most people's) is turning a time string into
>> a struct timespec. What the actual struct tm fields are is irrelevant to
>> that as long as mktime() translates the result back to the right number.
> 
> mktime interprets it as local, in which case strptime would have to be
> doing the inverse operation, converting from UTC to local for the
> struct tm output.
> 
> On the other hand strptime output may also be used with timegm (or a
> hand-rolled version thereof).

If mktime is in posix and timegm isn't, that probably means something.

People can write hand-rolled code to do anything, doesn't make it right.

> This is what you would do if you were
> parsing a sting in UTC. With all the existing/standard fields,
> strptime is completely agnostic with regards to what you want to do
> with the output. Only with %s will it need a hard-coded assumption
> about what you're going to do with the output.

Not if it's symmetrical. If I don't _change_ the time zone between
populating the struct tm and consuming the struct tm, I should get the
same result back out, which is what I'm trying to accomplish.

>From man timegm:

  For a portable version of timegm(), set the TZ environment variable
  to UTC, call mktime(3) and restore the value of TZ.

I.E. the "portable" behavior is symmetrical if you don't change the
timezone in the middle. If you do, that's obvious pilot error. And if I
want everything to happen in UTC, I can set TZ (which the date command
does for -u already).

>> The struct tm has a timezone field in it. As long as strptime sets the
>> timezone when it adjusts the hours so mktime() can adjust it _back_, the
>> result is the same number you fed into %s. Which is the point of the
>> exercise.
> 
> mktime cannot use the timezone field of struct tm. It's required to
> assume the struct tm is in local time in the current timezone.

As long as it's symmetrical, it works for me. If posix requires mktime
to use the current timezone and that's the _only_ way it provides of
turning struct tm into time_t, then it implicitly requires strptime to
mirror that when turning an ascii representation of time_t into a struct
tm. It needs to do the opposite of what mktime does, so mktime can undo it.

> Rich

Rob
___
Toybox mailing list
Toybox@lists.landley.net
http://lists.landley.net/listinfo.cgi/toybox-landley.net


Re: [Toybox] Stat %Z - What are valid values?

2017-01-25 Thread Rich Felker
On Wed, Jan 25, 2017 at 05:15:37PM -0600, Rob Landley wrote:
> On 01/24/2017 06:10 PM, Rich Felker wrote:
> >>> strptime with %s? I suspect there are some nasty underspecified issues
> >>> with how it interacts with timezones.
> >>
> >> I thought unix time was always UTS and the timezone just affected how it
> >> was displayed?
> > 
> > The problem is that strptime produces a struct tm. When the fields
> > it's parsing to produce this struct tm are "broken down time" fields,
> > strptime does not need to know/care whether the caller is going to
> > interpret the struct tm as UTC or local time; it's just a bunch of
> > numbers. But when strptime is going to take a unix time value (seconds
> > since epoch) and convert it to struct tm, it matters whether the
> > caller is supposed to treat that struct tm as UTC or local.
> 
> According to man 2 time:
> 
>  time()  returns  the  time  as  the  number of seconds since the Epoch,
>  1970-01-01 00:00:00 + (UTC).
> 
> I.E. the definition of unix time is UTC. So %s _not_ being UTC is silly.

Nobody is questioning whether the input read by %s is UTC. The
question is whether the output struct tm is UTC or local.

> My use case (and presumably most people's) is turning a time string into
> a struct timespec. What the actual struct tm fields are is irrelevant to
> that as long as mktime() translates the result back to the right number.

mktime interprets it as local, in which case strptime would have to be
doing the inverse operation, converting from UTC to local for the
struct tm output.

On the other hand strptime output may also be used with timegm (or a
hand-rolled version thereof). This is what you would do if you were
parsing a sting in UTC. With all the existing/standard fields,
strptime is completely agnostic with regards to what you want to do
with the output. Only with %s will it need a hard-coded assumption
about what you're going to do with the output.

> The struct tm has a timezone field in it. As long as strptime sets the
> timezone when it adjusts the hours so mktime() can adjust it _back_, the
> result is the same number you fed into %s. Which is the point of the
> exercise.

mktime cannot use the timezone field of struct tm. It's required to
assume the struct tm is in local time in the current timezone.

Rich
___
Toybox mailing list
Toybox@lists.landley.net
http://lists.landley.net/listinfo.cgi/toybox-landley.net


Re: [Toybox] Stat %Z - What are valid values?

2017-01-25 Thread Rob Landley
On 01/24/2017 06:10 PM, Rich Felker wrote:
>>> strptime with %s? I suspect there are some nasty underspecified issues
>>> with how it interacts with timezones.
>>
>> I thought unix time was always UTS and the timezone just affected how it
>> was displayed?
> 
> The problem is that strptime produces a struct tm. When the fields
> it's parsing to produce this struct tm are "broken down time" fields,
> strptime does not need to know/care whether the caller is going to
> interpret the struct tm as UTC or local time; it's just a bunch of
> numbers. But when strptime is going to take a unix time value (seconds
> since epoch) and convert it to struct tm, it matters whether the
> caller is supposed to treat that struct tm as UTC or local.

According to man 2 time:

 time()  returns  the  time  as  the  number of seconds since the Epoch,
 1970-01-01 00:00:00 + (UTC).

I.E. the definition of unix time is UTC. So %s _not_ being UTC is silly.

My use case (and presumably most people's) is turning a time string into
a struct timespec. What the actual struct tm fields are is irrelevant to
that as long as mktime() translates the result back to the right number.
The struct tm has a timezone field in it. As long as strptime sets the
timezone when it adjusts the hours so mktime() can adjust it _back_, the
result is the same number you fed into %s. Which is the point of the
exercise.

(Remember when Linux systems used to have a "store system clock in GMT
instead of localtime" option during config, and the config option went
away because nobody ever _didn't_ do that? Yeah, that.)

> Rich

Rob
___
Toybox mailing list
Toybox@lists.landley.net
http://lists.landley.net/listinfo.cgi/toybox-landley.net


Re: [Toybox] Stat %Z - What are valid values?

2017-01-24 Thread Rich Felker
On Tue, Jan 24, 2017 at 05:47:46PM -0600, Rob Landley wrote:
> 
> 
> On 01/21/2017 06:25 PM, Rich Felker wrote:
> > On Sat, Jan 21, 2017 at 03:18:28PM -0600, Rob Landley wrote:
> >>> Or if it's signed, that's -1346458162 which would be... sometime in the
> >>> 1930's? hmmm... "./date -D %s -d -1346458162" is failing under glibc,
> >>> and failing _differently_ under musl. (Wheee.)
> >>>
> >>> /me goes down tangent rathole debugging why.
> >> 
> >>>
> >>> (Answer: musl doesn't implement %s at all, and glibc doesn't allow the
> >>> %s value it converts to be negative.)
> >>
> >> Query: does bionic strptime() handle %s, and if so does it handle
> >> negative input values? (If not I suppose I can try to special case this
> >> in toybox, but ew.)
> >>
> >> Also, Rich: any interest in adding this to musl?
> > 
> > strptime with %s? I suspect there are some nasty underspecified issues
> > with how it interacts with timezones.
> 
> I thought unix time was always UTS and the timezone just affected how it
> was displayed?

The problem is that strptime produces a struct tm. When the fields
it's parsing to produce this struct tm are "broken down time" fields,
strptime does not need to know/care whether the caller is going to
interpret the struct tm as UTC or local time; it's just a bunch of
numbers. But when strptime is going to take a unix time value (seconds
since epoch) and convert it to struct tm, it matters whether the
caller is supposed to treat that struct tm as UTC or local.

Rich
___
Toybox mailing list
Toybox@lists.landley.net
http://lists.landley.net/listinfo.cgi/toybox-landley.net


Re: [Toybox] Stat %Z - What are valid values?

2017-01-24 Thread enh
On Tue, Jan 24, 2017 at 3:47 PM, Rob Landley  wrote:
>
>
> On 01/21/2017 06:25 PM, Rich Felker wrote:
>> On Sat, Jan 21, 2017 at 03:18:28PM -0600, Rob Landley wrote:
 Or if it's signed, that's -1346458162 which would be... sometime in the
 1930's? hmmm... "./date -D %s -d -1346458162" is failing under glibc,
 and failing _differently_ under musl. (Wheee.)

 /me goes down tangent rathole debugging why.
>>> 

 (Answer: musl doesn't implement %s at all, and glibc doesn't allow the
 %s value it converts to be negative.)
>>>
>>> Query: does bionic strptime() handle %s, and if so does it handle
>>> negative input values? (If not I suppose I can try to special case this
>>> in toybox, but ew.)
>>>
>>> Also, Rich: any interest in adding this to musl?
>>
>> strptime with %s? I suspect there are some nasty underspecified issues
>> with how it interacts with timezones.
>
> I thought unix time was always UTS and the timezone just affected how it
> was displayed?
>
>> All the standard specifiers work
>> with broken-down (struct tm) time so timezone is irrelevant to how
>> they operate.
>
> I'm tempted to add support for it myself, but the problem is the format
> could be "time=[%s]" and I'd have to parse context data. (I can just
> strstr() but I'd have to make sure it wasn't %%s...)
>
>> So the answer isn't no, but "it's complicated", and needs more
>> research on how other implementations work,
>
> I think it's just glibc so far?

i have an open feature request for %s in bionic
(http://code.google.com/p/android/issues/detail?id=229155) and iirc
freebsd and netbsd both have it, but different (gmtime versus
localtime). openbsd didn't have it. ios matches freebsd. which meant
ios and glibc disagree, which is why that's on my big list of things
i'm not sure what to do about. glibc was probably there first, but ios
is probably more relevant.

i'd rather work on making the icu4c APIs available to apps anyway :-)

>> if they're consistent,
>> pros and cons of different possible behaviors, etc.
>
> It's not that big a deal for me to do it myself, I just thought I'd
> raise the issue. If bionic and musl both add %s that supports negative
> numbers, I'm happy to leave glibc as broken until they catch up. If they
> don't, it makes sense to do it myself...
>
>> Rich
>
> Rob



-- 
Elliott Hughes - http://who/enh - http://jessies.org/~enh/
Android native code/tools questions? Mail me/drop by/add me as a reviewer.
___
Toybox mailing list
Toybox@lists.landley.net
http://lists.landley.net/listinfo.cgi/toybox-landley.net


Re: [Toybox] Stat %Z - What are valid values?

2017-01-24 Thread Rob Landley


On 01/21/2017 06:25 PM, Rich Felker wrote:
> On Sat, Jan 21, 2017 at 03:18:28PM -0600, Rob Landley wrote:
>>> Or if it's signed, that's -1346458162 which would be... sometime in the
>>> 1930's? hmmm... "./date -D %s -d -1346458162" is failing under glibc,
>>> and failing _differently_ under musl. (Wheee.)
>>>
>>> /me goes down tangent rathole debugging why.
>> 
>>>
>>> (Answer: musl doesn't implement %s at all, and glibc doesn't allow the
>>> %s value it converts to be negative.)
>>
>> Query: does bionic strptime() handle %s, and if so does it handle
>> negative input values? (If not I suppose I can try to special case this
>> in toybox, but ew.)
>>
>> Also, Rich: any interest in adding this to musl?
> 
> strptime with %s? I suspect there are some nasty underspecified issues
> with how it interacts with timezones.

I thought unix time was always UTS and the timezone just affected how it
was displayed?

> All the standard specifiers work
> with broken-down (struct tm) time so timezone is irrelevant to how
> they operate.

I'm tempted to add support for it myself, but the problem is the format
could be "time=[%s]" and I'd have to parse context data. (I can just
strstr() but I'd have to make sure it wasn't %%s...)

> So the answer isn't no, but "it's complicated", and needs more
> research on how other implementations work,

I think it's just glibc so far?

> if they're consistent,
> pros and cons of different possible behaviors, etc.

It's not that big a deal for me to do it myself, I just thought I'd
raise the issue. If bionic and musl both add %s that supports negative
numbers, I'm happy to leave glibc as broken until they catch up. If they
don't, it makes sense to do it myself...

> Rich

Rob
___
Toybox mailing list
Toybox@lists.landley.net
http://lists.landley.net/listinfo.cgi/toybox-landley.net


Re: [Toybox] Stat %Z - What are valid values?

2017-01-21 Thread Rich Felker
On Sat, Jan 21, 2017 at 03:18:28PM -0600, Rob Landley wrote:
> > Or if it's signed, that's -1346458162 which would be... sometime in the
> > 1930's? hmmm... "./date -D %s -d -1346458162" is failing under glibc,
> > and failing _differently_ under musl. (Wheee.)
> > 
> > /me goes down tangent rathole debugging why.
> 
> > 
> > (Answer: musl doesn't implement %s at all, and glibc doesn't allow the
> > %s value it converts to be negative.)
> 
> Query: does bionic strptime() handle %s, and if so does it handle
> negative input values? (If not I suppose I can try to special case this
> in toybox, but ew.)
> 
> Also, Rich: any interest in adding this to musl?

strptime with %s? I suspect there are some nasty underspecified issues
with how it interacts with timezones. All the standard specifiers work
with broken-down (struct tm) time so timezone is irrelevant to how
they operate.

So the answer isn't no, but "it's complicated", and needs more
research on how other implementations work, if they're consistent,
pros and cons of different possible behaviors, etc.

Rich
___
Toybox mailing list
Toybox@lists.landley.net
http://lists.landley.net/listinfo.cgi/toybox-landley.net


Re: [Toybox] Stat %Z - What are valid values?

2017-01-21 Thread Rob Landley
On 12/30/2016 04:01 PM, enh wrote:
> On Fri, Dec 30, 2016 at 1:51 PM, Rob Landley  wrote:
>> On 12/30/2016 01:39 PM, enh wrote:
>>> 1928-04-26 17:31:55.746667836 18446744072394174731
>>
>> Really we can partially blame posix here for not specifying whether
>> time_t is signed or unsigned. (If it's unsigned it can't represent times
>> before January 1, 1970, as the code on the left is doing. And there
>> _are_ times before then. So I think we have to treat it as signed and go
>> "32 bit timestamps gotta go away before 2038".)
> 
> if you want to be amused/horrified, you should look at the tzcode
> stuff. iirc they only recently agreed that time_t is an integral type.

Note to self: it's easier to review patches after a while if you include
the test case of the thing it fixes in the patch.

Right, this thread...

> Or if it's signed, that's -1346458162 which would be... sometime in the
> 1930's? hmmm... "./date -D %s -d -1346458162" is failing under glibc,
> and failing _differently_ under musl. (Wheee.)
> 
> /me goes down tangent rathole debugging why.
...
> 
> (Answer: musl doesn't implement %s at all, and glibc doesn't allow the
> %s value it converts to be negative.)

Query: does bionic strptime() handle %s, and if so does it handle
negative input values? (If not I suppose I can try to special case this
in toybox, but ew.)

Also, Rich: any interest in adding this to musl?

> with 64-bit toybox:
> 
> angler:/ # date 06022064
> Mon Jun  2 00:00:00 GMT 2064

Under Ubuntu 14.04 with 64-bit glibc, that becomes

  $ ./date 06022064
  date: bad date '06022064'; Fri Jun  2 00:00:00 CST 2064 != Mon
  Jun  2 01:00:00 CDT 2064

So it's adjusting it for daylight savings time, and breaking.

Sigh. _Why_ are we doing this date normalization checking thing again?
It's kinda brittle. I'm starting to remember why this got pushed onto
the todo stack. (Which is really a todo heap with a leaking problem.)

Rob
___
Toybox mailing list
Toybox@lists.landley.net
http://lists.landley.net/listinfo.cgi/toybox-landley.net


Re: [Toybox] Stat %Z - What are valid values?

2016-12-30 Thread Rob Landley
On 12/30/2016 01:39 PM, enh wrote:
> 1928-04-26 17:31:55.746667836 18446744072394174731

Really we can partially blame posix here for not specifying whether
time_t is signed or unsigned. (If it's unsigned it can't represent times
before January 1, 1970, as the code on the left is doing. And there
_are_ times before then. So I think we have to treat it as signed and go
"32 bit timestamps gotta go away before 2038".)

Linus' opinion on unsigned time_t is here (spoiler: it's "no"):

  https://lkml.org/lkml/2011/8/31/246

> two patches attached.
...
> the other
> removes void* casts unnecessary since POSIX 2008 and fixes the
> strftime buffer length argument.

Why did you remove the comment block in the second patch? (Is it wrong?)

Rob
___
Toybox mailing list
Toybox@lists.landley.net
http://lists.landley.net/listinfo.cgi/toybox-landley.net


Re: [Toybox] Stat %Z - What are valid values?

2016-12-30 Thread Rob Landley
I have negotiated a 3 day weekend for the holidays! Starting today. Ok,
catching up...

On 12/30/2016 01:39 PM, enh wrote:
> time_t on 32-bit Android is 32 bits.
> 
> that particular value looks like a sign-extension of 0xAFBEADCE, which
> is still some time in 2063.

Or if it's signed, that's -1346458162 which would be... sometime in the
1930's? hmmm... "./date -D %s -d -1346458162" is failing under glibc,
and failing _differently_ under musl. (Wheee.)

/me goes down tangent rathole debugging why. (THIS is why I need to
finish mkroot and get a toybox test environment set up that can test
stuff requiring root access under qemu under a known root filesystem and
kernel config. Is my code broken, or does strptime not parse negative
numerical arguments for %s format?)

(Answer: musl doesn't implement %s at all, and glibc doesn't allow the
%s value it converts to be negative. And of course posix doesn't specify
signed OR unsigned for time_t at
http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_types.h.html
because actually providing enough detail to implement things would be
_useful_.)

> two patches attached. one avoids sign extension for all calls to
> `out`, fixing %Z for systems with a signed 32-bit time_t.

The 0001-Avoid* patch only has the first hunk, which defines two macros
there are never used and renames a function but not its users.

>> This seems suspiciously large and I'm wondering what the valid range for
>> this value is.

I think we all do at this point.

Rob
___
Toybox mailing list
Toybox@lists.landley.net
http://lists.landley.net/listinfo.cgi/toybox-landley.net


Re: [Toybox] Stat %Z - What are valid values?

2016-12-30 Thread enh
time_t on 32-bit Android is 32 bits.

that particular value looks like a sign-extension of 0xAFBEADCE, which
is still some time in 2063. (so i'd assume this device's clock is set
wrong, and i'd assume -- since this is presumably a 32-bit device with
a signed 32-bit time_t -- that that's going to be causing other
problems too.)

https://android.googlesource.com/platform/external/toybox/+/android-6.0.1_r77/toys/other/stat.c
doesn't look to different from today.

with 64-bit toybox:

angler:/ # date 06022064
Mon Jun  2 00:00:00 GMT 2064
angler:/ # rm /data/local/tmp/empty
angler:/ # touch /data/local/tmp/empty
angler:/ # ls -l /data/local/tmp/empty
-rw-rw-rw- 1 root root 0 2064-06-02 00:00 /data/local/tmp/empty
angler:/ # stat /data/local/tmp/empty
  File: `/data/local/tmp/empty'
  Size: 0 Blocks: 0 IO Blocks: 512 regular empty file
Device: fd00h/64768d Inode: 3014659 Links: 1
Access: (666/-rw-rw-rw-) Uid: (0/root) Gid: (0/root)
Access: 2064-06-02 00:00:11.746667836
Modify: 2064-06-02 00:00:11.746667836
Change: 2064-06-02 00:00:11.746667836
angler:/ # stat -c "%z %Z" /data/local/tmp/empty
2064-06-02 00:00:11.746667836 2979590411
angler:/ # ^D

then with 32-bit toybox:

angler:/ # ls -l /data/local/tmp/empty
-rw-rw-rw- 1 root root 0 1928-04-26 17:31 /data/local/tmp/empty
angler:/ # stat /data/local/tmp/empty
  File: `/data/local/tmp/empty'
  Size: 0 Blocks: 0 IO Blocks: 512 regular empty file
Device: fd00h/64768d Inode: 3014659 Links: 1
Access: (666/-rw-rw-rw-) Uid: (0/root) Gid: (0/root)
Access: 1928-04-26 17:31:55.746667836
Modify: 1928-04-26 17:31:55.746667836
Change: 1928-04-26 17:31:55.746667836
angler:/ # stat -c "%z %Z" /data/local/tmp/empty
1928-04-26 17:31:55.746667836 18446744072394174731

two patches attached. one avoids sign extension for all calls to
`out`, fixing %Z for systems with a signed 32-bit time_t. the other
removes void* casts unnecessary since POSIX 2008 and fixes the
strftime buffer length argument.

%z is still broken for systems with signed 32-bit time_t, but i think
that's just inherent on such systems.

On Fri, Dec 30, 2016 at 9:28 AM, darken  wrote:
> I've seen a value of "18446744072363093454" for stat %Z (seconds since
> epoch), for some files on a users device (Android 6.01).
>
> This seems suspiciously large and I'm wondering what the valid range for
> this value is.
> What range is valid for the filesystem to return and what value range can
> toybox handle?
>
> ~Matthias
>
> ___
> Toybox mailing list
> Toybox@lists.landley.net
> http://lists.landley.net/listinfo.cgi/toybox-landley.net
>



-- 
Elliott Hughes - http://who/enh - http://jessies.org/~enh/
Android native code/tools questions? Mail me/drop by/add me as a reviewer.
From be5dd0c57df9d35bff7671c897e0b2dd384bdb84 Mon Sep 17 00:00:00 2001
From: Elliott Hughes 
Date: Fri, 30 Dec 2016 11:24:25 -0800
Subject: [PATCH] Avoid sign extension in stat.c.

---
 toys/other/stat.c | 16 +---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/toys/other/stat.c b/toys/other/stat.c
index 9d64579..63dfba8 100644
--- a/toys/other/stat.c
+++ b/toys/other/stat.c
@@ -50,9 +50,19 @@ GLOBALS(
   int patlen;
 )
 
-// Force numeric output to long long instead of manually typecasting everything
-// and safely parse length prefix
-static void out(char c, long long val)
+// Force numeric output to unsigned long long instead of manually typecasting
+// everything. Takes unsigned because no struct stat field can be negative,
+// and in combination with the add_unsigned macro this lets us avoid
+// accidental sign extension of signed fields (time_t on LP32, say).
+// We also handle length prefixes here rather than repeating that everywhere.
+#define out(out_c, out_val) uout(out_c, add_unsigned(out_val))
+#define add_unsigned(x) \
+  (sizeof(x) == sizeof(char) ? (unsigned char)(x) : \
+   sizeof(x) == sizeof(short) ? (unsigned short)(x) : \
+   sizeof(x) == sizeof(int) ? (unsigned int)(x) : \
+   sizeof(x) == sizeof(long) ? (unsigned long)(x) : \
+   (unsigned long long)(x))
+static void uout(char c, unsigned long long val)
 {
   sprintf(toybuf, "%.*sll%c", TT.patlen, TT.pattern, c);
   printf(toybuf, val);
-- 
2.8.0.rc3.226.g39d4020

From 1c4a7a8ac7ff68e07df91f5822dd8145229e4bf9 Mon Sep 17 00:00:00 2001
From: Elliott Hughes 
Date: Fri, 30 Dec 2016 11:19:08 -0800
Subject: [PATCH] Remove unnecessary casts in stat.c, fix a claimed buffer
 length.

POSIX does have a name for the struct timespec in struct stat.
---
 toys/other/stat.c | 12 
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/toys/other/stat.c b/toys/other/stat.c
index b998a0e..9d64579 100644
--- a/toys/other/stat.c
+++ b/toys/other/stat.c
@@ -65,14 +65,10 @@ static void strout(char *val)
   printf(toybuf, val);
 }
 
-// Note: the atime, mtime, and ctime fields in struct stat are the start
-// of embedded struct