Closed Bug 1015824 Opened 10 years ago Closed 10 years ago

64-bit ints in StructuredClone are bogus on big-endian

Categories

(Core :: DOM: Workers, defect)

PowerPC
macOS
defect
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla33

People

(Reporter: spectre, Assigned: spectre)

References

Details

Attachments

(2 files)

"TenFourFox: Lie Cannot I And Endian Big Like I"

The StructuredClone implementation passes pointers in 64-bit ints that are actually little endian, even on big endian platforms, and causes naughty little assertions like

Assertion failure: contents, at /Volumes/BruceDeuce/src/mozilla-31a/js/src/vm/ArrayBufferObject.cpp:1055

The simple solution is just to wordswap the 64-bit ints as per the patch.
Attachment #8428493 - Flags: review?(sphink)
Assignee: nobody → spectre
Blocks: 912456
Review ping-a-ling (advise, Steve, if someone else should review).
Status: NEW → ASSIGNED
Flags: needinfo?(sphink)
Comment on attachment 8428493 [details] [diff] [review]
structured_clone_bige.diff

Shouldn't that be swapFromLittleEndian?  They accomplish the same thing, in this case, but it reads more correctly for big-endian machines, since presumably things are little-endian when they're being passed around, and you're trying to get the data back into native endianness.  I'd expect swapToLittleEndian to be used while writing, per the comments in Endian.h.
OK, that makes sense. I'll change it when I'm back at my desk.
Comment on attachment 8428493 [details] [diff] [review]
structured_clone_bige.diff

Review of attachment 8428493 [details] [diff] [review]:
-----------------------------------------------------------------

::: js/src/vm/StructuredClone.cpp
@@ +572,5 @@
>  {
>      uint64_t u;
>      if (!readNativeEndian(&u))
>          return false;
> +    *p = reinterpret_cast<void*>(NativeEndian::swapToLittleEndian(u));

Yeah, this should be swapFromLittleEndian.

readPtr/writePtr should die. But that's a separate bug. (Specifically, transferable clones should not pretend to serialize the transferred data. It should be in a separate auxiliary data structure using native types.)

I think my intent here was actually to not change endianness at all for pointers, since it's a lie that they can be serialized in the first place. But I'm ok either way, especially since I plan to eliminate it eventually anyway.

In other words: r=me if you change the above to swapFromLittleEndian. Alternatively, r=me if you change the body of writePtr:

-    return write(reinterpret_cast<uint64_t>(p));
+    return buf.append(reinterpret_cast<uint64_t>(p));

and then eliminate the endianness conversion entirely in readPtr.
Attachment #8428493 - Flags: review?(sphink) → review+
Flags: needinfo?(sphink)
Thanks for the review!

>+    return buf.append(reinterpret_cast<uint64_t>(p));

I'm puzzling over this. Unless I misunderstand what write() is doing, wouldn't this have the same problem?
(In reply to Cameron Kaiser [:spectre] from comment #5)
> Thanks for the review!
> 
> >+    return buf.append(reinterpret_cast<uint64_t>(p));
> 
> I'm puzzling over this. Unless I misunderstand what write() is doing,
> wouldn't this have the same problem?

Currently, pointers' endianness is flipped when writing them out (because writePtr calls write(uint64_t) which does NativeEndian::swapToLittleEndian) but not when reading them in.

So your fix is to flip them on both sides. An alternative would be to never flip them. This would be done by removing the swapToLittleEndian call, which ends up with the buf.append line of code above. It's the current SCOutput::write but without the endian swap.
Let me make sure we're talking about the right patch:

 bool
 SCOutput::writePtr(const void *p)
 {
-    return write(reinterpret_cast<uint64_t>(p));
+    return buf.append(reinterpret_cast<uint64_t>(p));
 }

still blows up. Did I need something else in there?
Attached patch For check-inSplinter Review
The swapFromLittleEndian() of course works, so I think I'll go with that, since you gave me the choice. Patch for checkin. Carrying r+.
Attachment #8439669 - Flags: review+
Keywords: checkin-needed
Can you please run this through Try (builds only is fine) just as a sanity check? :)
Keywords: checkin-needed
I don't have the ability to push to try. If someone can on my behalf I would appreciate it.
Comment on attachment 8439669 [details] [diff] [review]
For check-in

s/r=sphink/r=sfink/ and green on Try

https://tbpl.mozilla.org/?tree=Try&rev=438f9bf04477
Thanks, Jan!
Keywords: checkin-needed
https://hg.mozilla.org/mozilla-central/rev/9cd95132bc9f
Status: ASSIGNED → RESOLVED
Closed: 10 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla33
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: