fix(core): don't consider inherited NG_ELEMENT_ID during DI (#37574)
Special DI tokens like `ChangeDetectorRef` and `ElementRef` can provide a factory via `NG_ELEMENT_ID`. The problem is that we were reading it off the token as `token[NG_ELEMENT_ID]` which will go up the prototype chain if it couldn't be found on the current token, resulting in the private `ViewRef` API being exposed, because it extends `ChangeDetectorRef`. These changes fix the issue by guarding the property access with `hasOwnProperty`. Fixes #36235. PR Close #37574
This commit is contained in:
@ -99,8 +99,12 @@ let nextNgElementId = 0;
|
||||
export function bloomAdd(
|
||||
injectorIndex: number, tView: TView, type: Type<any>|InjectionToken<any>|string): void {
|
||||
ngDevMode && assertEqual(tView.firstCreatePass, true, 'expected firstCreatePass to be true');
|
||||
let id: number|undefined =
|
||||
typeof type !== 'string' ? (type as any)[NG_ELEMENT_ID] : type.charCodeAt(0) || 0;
|
||||
let id: number|undefined;
|
||||
if (typeof type === 'string') {
|
||||
id = type.charCodeAt(0) || 0;
|
||||
} else if (type.hasOwnProperty(NG_ELEMENT_ID)) {
|
||||
id = (type as any)[NG_ELEMENT_ID];
|
||||
}
|
||||
|
||||
// Set a unique ID on the directive type, so if something tries to inject the directive,
|
||||
// we can easily retrieve the ID and hash it into the bloom bit that should be checked.
|
||||
@ -584,7 +588,9 @@ export function bloomHashBitOrFactory(token: Type<any>|InjectionToken<any>|strin
|
||||
if (typeof token === 'string') {
|
||||
return token.charCodeAt(0) || 0;
|
||||
}
|
||||
const tokenId: number|undefined = (token as any)[NG_ELEMENT_ID];
|
||||
const tokenId: number|undefined =
|
||||
// First check with `hasOwnProperty` so we don't get an inherited ID.
|
||||
token.hasOwnProperty(NG_ELEMENT_ID) ? (token as any)[NG_ELEMENT_ID] : undefined;
|
||||
// Negative token IDs are used for special objects such as `Injector`
|
||||
return (typeof tokenId === 'number' && tokenId > 0) ? tokenId & BLOOM_MASK : tokenId;
|
||||
}
|
||||
|
Reference in New Issue
Block a user