466 // if this object is an instance member, the given object
467 // must be a subclass of the declaring class of this reflected object
468 if (!declaringClass.isAssignableFrom(obj.getClass())) {
469 throw new IllegalArgumentException("object is not an instance of "
470 + declaringClass.getName());
471 }
472 } else if (obj != null) {
473 throw new IllegalArgumentException("non-null object for " + this);
474 }
475
476 // access check is suppressed
477 if (override) return true;
478
479 Class<?> caller = Reflection.getCallerClass();
480 Class<?> targetClass;
481 if (this instanceof Constructor) {
482 targetClass = declaringClass;
483 } else {
484 targetClass = Modifier.isStatic(modifiers) ? null : obj.getClass();
485 }
486 return Reflection.verifyMemberAccess(caller,
487 declaringClass,
488 targetClass,
489 modifiers);
490 }
491
492 /**
493 * Constructor: only used by the Java Virtual Machine.
494 */
495 protected AccessibleObject() {}
496
497 // Indicates whether language-level access checks are overridden
498 // by this object. Initializes to "false". This field is used by
499 // Field, Method, and Constructor.
500 //
501 // NOTE: for security purposes, this field must not be visible
502 // outside this package.
503 boolean override;
504
505 // Reflection factory used by subclasses for creating field,
506 // method, and constructor accessors. Note that this is called
507 // very early in the bootstrapping process.
508 static final ReflectionFactory reflectionFactory =
509 AccessController.doPrivileged(
581 // it is necessary to perform somewhat expensive security checks.
582 // If the security check succeeds for a given class, it will
583 // always succeed (it is not affected by the granting or revoking
584 // of permissions); we speed up the check in the common case by
585 // remembering the last Class for which the check succeeded.
586 //
587 // The simple security check for Constructor is to see if
588 // the caller has already been seen, verified, and cached.
589 // (See also Class.newInstance(), which uses a similar method.)
590 //
591 // A more complicated security check cache is needed for Method and Field
592 // The cache can be either null (empty cache), a 2-array of {caller,targetClass},
593 // or a caller (with targetClass implicitly equal to memberClass).
594 // In the 2-array case, the targetClass is always different from the memberClass.
595 volatile Object securityCheckCache;
596
597 final void checkAccess(Class<?> caller, Class<?> memberClass,
598 Class<?> targetClass, int modifiers)
599 throws IllegalAccessException
600 {
601 if (caller == memberClass) { // quick check
602 return; // ACCESS IS OK
603 }
604 Object cache = securityCheckCache; // read volatile
605 if (targetClass != null // instance member or constructor
606 && Modifier.isProtected(modifiers)
607 && targetClass != memberClass) {
608 // Must match a 2-list of { caller, targetClass }.
609 if (cache instanceof Class[]) {
610 Class<?>[] cache2 = (Class<?>[]) cache;
611 if (cache2[1] == targetClass &&
612 cache2[0] == caller) {
613 return; // ACCESS IS OK
614 }
615 // (Test cache[1] first since range check for [1]
616 // subsumes range check for [0].)
617 }
618 } else if (cache == caller) {
619 // Non-protected case (or targetClass == memberClass or static member).
620 return; // ACCESS IS OK
621 }
622
623 // If no return, fall through to the slow path.
624 slowCheckMemberAccess(caller, memberClass, targetClass, modifiers);
625 }
626
627 // Keep all this slow stuff out of line:
628 void slowCheckMemberAccess(Class<?> caller, Class<?> memberClass,
629 Class<?> targetClass, int modifiers)
630 throws IllegalAccessException
631 {
632 Reflection.ensureMemberAccess(caller, memberClass, targetClass, modifiers);
633
634 // Success: Update the cache.
635 Object cache = (targetClass != null
636 && Modifier.isProtected(modifiers)
637 && targetClass != memberClass)
638 ? new Class<?>[] { caller, targetClass }
639 : caller;
640
641 // Note: The two cache elements are not volatile,
642 // but they are effectively final. The Java memory model
643 // guarantees that the initializing stores for the cache
644 // elements will occur before the volatile write.
645 securityCheckCache = cache; // write volatile
646 }
647 }
|
466 // if this object is an instance member, the given object
467 // must be a subclass of the declaring class of this reflected object
468 if (!declaringClass.isAssignableFrom(obj.getClass())) {
469 throw new IllegalArgumentException("object is not an instance of "
470 + declaringClass.getName());
471 }
472 } else if (obj != null) {
473 throw new IllegalArgumentException("non-null object for " + this);
474 }
475
476 // access check is suppressed
477 if (override) return true;
478
479 Class<?> caller = Reflection.getCallerClass();
480 Class<?> targetClass;
481 if (this instanceof Constructor) {
482 targetClass = declaringClass;
483 } else {
484 targetClass = Modifier.isStatic(modifiers) ? null : obj.getClass();
485 }
486 return verifyAccess(caller, declaringClass, targetClass, modifiers);
487 }
488
489 /**
490 * Constructor: only used by the Java Virtual Machine.
491 */
492 protected AccessibleObject() {}
493
494 // Indicates whether language-level access checks are overridden
495 // by this object. Initializes to "false". This field is used by
496 // Field, Method, and Constructor.
497 //
498 // NOTE: for security purposes, this field must not be visible
499 // outside this package.
500 boolean override;
501
502 // Reflection factory used by subclasses for creating field,
503 // method, and constructor accessors. Note that this is called
504 // very early in the bootstrapping process.
505 static final ReflectionFactory reflectionFactory =
506 AccessController.doPrivileged(
578 // it is necessary to perform somewhat expensive security checks.
579 // If the security check succeeds for a given class, it will
580 // always succeed (it is not affected by the granting or revoking
581 // of permissions); we speed up the check in the common case by
582 // remembering the last Class for which the check succeeded.
583 //
584 // The simple security check for Constructor is to see if
585 // the caller has already been seen, verified, and cached.
586 // (See also Class.newInstance(), which uses a similar method.)
587 //
588 // A more complicated security check cache is needed for Method and Field
589 // The cache can be either null (empty cache), a 2-array of {caller,targetClass},
590 // or a caller (with targetClass implicitly equal to memberClass).
591 // In the 2-array case, the targetClass is always different from the memberClass.
592 volatile Object securityCheckCache;
593
594 final void checkAccess(Class<?> caller, Class<?> memberClass,
595 Class<?> targetClass, int modifiers)
596 throws IllegalAccessException
597 {
598 if (!verifyAccess(caller, memberClass, targetClass, modifiers)) {
599 Reflection.throwIllegalAccessException(
600 caller, memberClass, targetClass, modifiers);
601 }
602 }
603
604 final boolean verifyAccess(Class<?> caller, Class<?> memberClass,
605 Class<?> targetClass, int modifiers)
606 {
607 if (caller == memberClass) { // quick check
608 return true; // ACCESS IS OK
609 }
610 Object cache = securityCheckCache; // read volatile
611 if (targetClass != null // instance member or constructor
612 && Modifier.isProtected(modifiers)
613 && targetClass != memberClass) {
614 // Must match a 2-list of { caller, targetClass }.
615 if (cache instanceof Class[]) {
616 Class<?>[] cache2 = (Class<?>[]) cache;
617 if (cache2[1] == targetClass &&
618 cache2[0] == caller) {
619 return true; // ACCESS IS OK
620 }
621 // (Test cache[1] first since range check for [1]
622 // subsumes range check for [0].)
623 }
624 } else if (cache == caller) {
625 // Non-protected case (or targetClass == memberClass or static member).
626 return true; // ACCESS IS OK
627 }
628
629 // If no return, fall through to the slow path.
630 return slowVerifyAccess(caller, memberClass, targetClass, modifiers);
631 }
632
633 // Keep all this slow stuff out of line:
634 private boolean slowVerifyAccess(Class<?> caller, Class<?> memberClass,
635 Class<?> targetClass, int modifiers)
636 {
637 if (Reflection.verifyMemberAccess(caller, memberClass, targetClass, modifiers)) {
638 // Success: Update the cache.
639 Object cache = (targetClass != null
640 && Modifier.isProtected(modifiers)
641 && targetClass != memberClass)
642 ? new Class<?>[] { caller, targetClass }
643 : caller;
644
645 // Note: The two cache elements are not volatile,
646 // but they are effectively final. The Java memory model
647 // guarantees that the initializing stores for the cache
648 // elements will occur before the volatile write.
649 securityCheckCache = cache; // write volatile
650 return true;
651 } else {
652 return false;
653 }
654 }
655 }
|