Bug 35789

Critical

GemBuilder for Smalltalk

5.2.5, 5.2.4

VA

5.3, 5.2.6

Large integers have wrong value after re-fault to client

When a server large integer is initially faulted to a GBS client, the
value is correct. If that client large integer is garbage collected,
and later re-faulted to the GBS client, the the client value is
correct.

However, if the same (identical) server large integer is re-faulted to
the client to the same client large integer in the same session, the
value of the client large integer will be changed to an incorrect
value that does not match the value of the server large integer.

Re-faulting of the same integer can occur if that integer is
referenced by another object that is being faulted, and the fault
level or replication specification includes that integer.

This problem does not affect VisualWorks clients, only VisualAge and
VA Smalltalk clients.

We recommend that all customers that are potentially affected modify
their GBS as shown in the Workaround section of this bug note.

Workaround:

This problem will not occur if the following code change is made in GBS:

Add these lines to the beginning of LargeInteger>>gbxUpdateFromReport:

     "Fix for bug 35789 -- zero if this is first report"
     report firstOffset = 1 ifTrue:
          [1 to: self size do:
               [:each | self at: each put: 0]].


The method then looks like this:

gbxUpdateFromReport: report
     "Modify my state to be consistent with the given object report.
     This report may be partial if my server value was split across traversal buffers.
     This could be an initial creation or a re-traversal of an existing client large integer.
     If report is the first report for me, we must clear contents to zero before updating,
     or final value will be wrong."

     | accessor |
     "Fix for bug 35789 -- zero if this is first report"
     report firstOffset = 1 ifTrue:
          [1 to: self size do:
               [:each | self at: each put: 0]].
     accessor := (GbxLargeIntAccessor classForReport: report) on: self.
     0 to: report valueBuffSize - 1
          do:
               [:bufOffset |
               accessor at: bufOffset + report firstOffset
                    put: (report valueByteAt: bufOffset)].
     "If we've just populated the highest-order bits, we now have enough information
     to set my final size. I may have leading zeroes if we didn't have the whole object
     in the initial report and we had to estimate my size."
     report containsHighestObjectIndex ifTrue: [accessor finish]


Last updated: 11/6/06