Errors Removing from GRSmallDictionary2

While working on Pier 3.3 on Pharo 7, ran into an error when executing any command (such as login):

SubscriptOutOfBounds: 10
Debug Full Stack
Stack Trace
thisContext
Array(Object)>>errorSubscriptBounds:
self
#('_s' '6gvRq_j2ds1erGA-' '_k' 'RaIHqXKHiClDYlCH' 'command' 'PULogin')

This error is failing in PRContext>>urlOn:when calling #purgeOtherFields (this is the only sender of this, the error leads to a errorSubscriptBounds). Comparing the 3.3 image with Pier 3.2:

  • Both have WAUrl>>purgeOtherFields as an extension in Pier
  • For 3.2, it has WARequestFields as a child of GROrderedMultiMap, GROrderedMultiMap2 for this version (same code in #removeKey:ifAbsent:).

Running a small test:

(WARequestFields new: 2) add: 1 -> 'one'; add: 2 -> 'two'; removeKey: 2 ifAbsent: [self halt]; yourself.

This will raise the same errorSubscriptBounds. The same test can be repeated with the same results higher up in the class hierarchy:

(GRSmallDictionary2 new: 2) add: 1 -> 'one'; add: 2 -> 'two'; removeKey: 2 ifAbsent: [self halt]; yourself.

These classes have the table of data setup as alternating keys and values:

#(1 'one' 2 'two')

The problem is that #findIndexFor: returns the index of the key in terms of the array, not in terms of the map - it can have a value larger than self size.

For a short term solution created a test from the above remove, and this method:

WARequestFields>>removeIndex: index
	| value |
	value := table at: index + 1.
	index to: size * 2 - 2 do: [ :i | table at: i put: (table at: i + 2) ].
	table at: size * 2 - 1 put: nil.
	table at: size * 2 put: nil.
	size := size - 1.
	^ value

As of 2019-April (or maybe earlier) this has been fixed in Grease.

Posted by John Borden at 25 March 2019, 12:37 pm link