Skip to content

compiler doesn't detect leakage of a class with qualified private access modifier via companion object methods #12128

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
unkarjedy opened this issue Aug 25, 2020 · 3 comments
Labels

Comments

@unkarjedy
Copy link

unkarjedy commented Aug 25, 2020

(original question: https://gitter.im/scala/scala?at=5f4510cb59ac794e02c5aaa9)

reproduction steps

using Scala (2.12.10, 2.13.3),

object org {

  import org.aaa.bbb.{MyClass1, MyClass2, MyClass3}

  object aaa {
    object bbb {
      private class MyClass1 { def foo = 1 }
      /**
       * compile error: {{{
       * private class MyClass1 escapes its defining scope as part of type org.aaa.bbb.MyClass1
       *     object MyClass1 { def apply(): MyClass1 = new MyClass1() }
       * }}}
       */
      //object MyClass1 { def apply(): MyClass1 = new MyClass1() }

      private[bbb] class MyClass2 { def foo = 1 }
      object MyClass2 { def apply(): MyClass2 = new MyClass2() }

      private[aaa] class MyClass3 { def foo = 1 }
      object MyClass3 { def apply(): MyClass3 = new MyClass3() }
    }
  }

  object UsageOrg {
    //println(new MyClass1) // inaccessible
    //println(MyClass1)     // inaccessible
    //println(MyClass1())   // inaccessible

    //println(new MyClass2) // inaccessible
    println(MyClass2)
    println(MyClass2())
    //println(MyClass2(): org.aaa.bbb.MyClass2$.apply) inaccessible
    println(MyClass2().foo)

    //println(new MyClass3) // inaccessible
    println(MyClass3)
    println(MyClass3())
    //println(MyClass3(): org.aaa.bbb.MyClass3) // inaccessible
    println(MyClass3().foo)
  }
}

problem

If you try to uncomment object MyClass1 you will gen compilation error:

object MyClass1 { def apply(): MyClass1 = new MyClass1() }
private class MyClass1 escapes its defining scope as part of type org.aaa.bbb.MyClass1
     object MyClass1 { def apply(): MyClass1 = new MyClass1() }

It's understandable...

private[bbb] should be the same as private,
But compiler generates no error for object MyClass2
Thus you can use any MyClass2 public methods via calling companion object apply method MyClass2().foo from any package

@SethTisue
Copy link
Member

Dotty, same.

@som-snytt
Copy link

som-snytt commented Aug 25, 2020

I'm pretty sure this backdoor access has always been true; I remember being surprised by it.

The closest ticket I find for linking is #11339 ("qualified private/protected have no chance whatsoever of ever working correctly") from 2017 or #5008 ("There are so many access related tickets open I can't tell in a reasonable amount of time if this already exists." "Overtaken by events." "Nifty.") from 2011.

The canonical ticket #6794 mentions #1800 which is still open.

The question whether private is "the same" as private[pkg] is interesting to debate over qualifying beverages. (Edit: it's not the same, spoiler alert.)

@SethTisue SethTisue added this to the Backlog milestone Oct 12, 2020
@som-snytt
Copy link

som-snytt commented Jul 20, 2021

This is 1800 but the dotty ticket linked there is closed to wait and see if they ditch qualified private scala/scala3#3870 (comment)

@SethTisue SethTisue removed this from the Backlog milestone Jul 20, 2021
@som-snytt som-snytt closed this as not planned Won't fix, can't repro, duplicate, stale Jul 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants