切入点
重点还是在ChainedTransformer
中找transform
的调用
再找谁的readObject
调用了compare
在PriorityQueue
这个类中,发现readObject
调用了heapify
,
private void heapify() {
for (int i = (size >>> 1) - 1; i >= 0; i--)
siftDown(i, (E) queue[i]); //----siftDown---
}
private void siftDown(int k, E x) {
if (comparator != null)
siftDownUsingComparator(k, x); ///---siftDownUsingComparator---
else
siftDownComparable(k, x);
}
private void siftDownUsingComparator(int k, E x) {
int half = size >>> 1;
while (k < half) {
int child = (k << 1) + 1;
Object c = queue[child];
int right = child + 1;
if (right < size &&
comparator.compare((E) c, (E) queue[right]) > 0)
c = queue[child = right];
if (comparator.compare(x, (E) c) <= 0) //----comparator--
break;
queue[k] = c;
k = child;
}
queue[k] = x;
}
切入
代码执行的地方和CC3一样
运行、无报错、无弹窗。下断点调试
步入
可以看见运行到这 seize=0,进不去siftDown,当size至少为2时,此时运算后、能进去siftDown,
此时size为2,运行报错,报错,报错的原因时第二个priorityQueue.add
。
因为add
方法调用了offer
,offer
调用了siftUp
,siftUp
调用了siftUpUsingComparator
,siftUpUsingComparator
调用了compare
这里调用了compare
方法、就会往下走调用transform
…、就在本地直接执行了。
此处的报错是因为 CC3中的_tfactory
反序列化时才会加进来的,现在本地没有,加上后就不会报错了。
这里就需要修改一些东西(TransformingComparator
),然后再序列化时复原,就不会导致本地执行了。
评论区