Skip to content

IndexOutOfBoundsException during SWAR string encoding #859

Description

@sl0thentr0py

We're seeing this error on our CI with v2.14.0 on jruby-9.4.12.0

     Failure/Error: Unable to find java.base/java.nio.Buffer.checkIndex(Buffer.java to read failed line
     Java::JavaLang::IndexOutOfBoundsException:
     # java.base/java.nio.Buffer.checkIndex(Buffer.java:749)
     # java.base/java.nio.HeapByteBuffer.getInt(HeapByteBuffer.java:439)
     # json.ext.SWARBasicStringEncoder.encode(SWARBasicStringEncoder.java:47)
     # json.ext.StringEncoder.generate(StringEncoder.java:171)
     # json.ext.Generator.generateString(Generator.java:672)
     # json.ext.Generator.generateFor(Generator.java:168)
     # json.ext.Generator.processEntry(Generator.java:650)
     # json.ext.Generator.generateHash(Generator.java:580)
     # json.ext.Generator.generateFor(Generator.java:174)
     # json.ext.Generator.processEntry(Generator.java:650)
     # json.ext.Generator.generateHash(Generator.java:580)
     # json.ext.Generator$HashHandler.generate(Generator.java:489)
     # json.ext.Generator$HashHandler.generate(Generator.java:475)
     # json.ext.Generator$Handler.generateToBuffer(Generator.java:264)
     # json.ext.Generator$Handler.generateNew(Generator.java:258)
     # json.ext.Generator.generateJson(Generator.java:85)
     # json.ext.GeneratorState.generate(GeneratorState.java:236)
     # json.ext.GeneratorState.generate(GeneratorState.java:138)

https://github.com/getsentry/sentry-ruby/actions/runs/17797166961/job/50676908911#step:6:289

Activity

  1. byroot commented on Sep 18, 2025

    @byroot
    Member

    Sadly I don't know much about Java / JRuby, but I assume it's a result of #835.

    @headius / @samyron could one of you take care of this?

  2. headius commented on Sep 18, 2025

    @headius
    Contributor

    This is likely a result of the extension being built with a newer Java than 1.8. there are ways we can fix the build so that that can still work, but the short-term fix would be to use Java 1.8 to build and re-release the Java extension.

    The problem is that the method it's using is from a newer version of Java so when it runs on the older version it can't find it.

  3. byroot commented on Sep 18, 2025

    @byroot
    Member

    Isn't it what

    json/Rakefile

    Line 143 in 55552ca

    sh 'javac', '-classpath', classpath, '-source', '1.8', '-target', '1.8', src
    is for?

    Why would it suddenly be a problem? I don't want to have to deal with figuring out how to downgrade to Java 8 on my machine.

  4. samyron commented on Sep 18, 2025

    @samyron
    Contributor

    Could this actually be a bug?

    int ptr = src.begin();
    
    ...
    
    if (pos + 4 <= len) {
        int x = bb.getInt(ptr + pos);
        if (skipChunk(x)) {
            pos += 4;
        }
    }
    

    If ptr = 0 then all is fine... if ptr > 0 then we may read off the end of the buffer.

  5. samyron commented on Sep 18, 2025

    @samyron
    Contributor

    It looks like there are a few instances in this class where I missed that...

  6. byroot commented on Sep 18, 2025

    @byroot
    Member

    Could this actually be a bug?

    Right the error message is a bit misleading. It complains about a missing function, but that's after it ran into an IndexOutOfBoundsException which seem to be the root cause.

  7. samyron commented on Sep 18, 2025

    @samyron
    Contributor

    I don't use java regularly any longer (so it's possible the format of the exception messages changed) but when it can't find a method due to classpath incompatibility we should (or at least used to) receive a java.lang.NoSuchMethodError. This would when compiling against one version of a library but running against another version that didn't have that method.

    I'll spin up a PR really quick...

  8. byroot commented on Sep 18, 2025

    @byroot
    Member

    @sl0thentr0py could you try #860 ? You should be able to point your gemfile to it assuming recent enough bundler:

    gem "json", github: "https://github.com/ruby/json/pull/860"
  9. samyron commented on Sep 18, 2025

    @samyron
    Contributor

    Looking back at 2.13.2 I'm now not quite convinced the fix in the PR is correct or the root cause.

    int ptr = src.begin();
    ...
    
    while (pos < len) {
       int ch = Byte.toUnsignedInt(ptrBytes[ptr + pos]);
    }
    

    I would have expected that to raise an IndexOutOfBoundsException if ptr > 0.

  10. headius commented on Sep 18, 2025

    @headius
    Contributor

    I am away from my computer but I can help in a while or tomorrow. Still pretty sure this is a problem of compiling against a newer version, and the source and target flags only set the version of bytecode that gets emitted. There is a separate flag that would force it to use older versions of APIs... But that flag only exists on newer versions of java which would prevent this from building on 1.8.

    Basically like compiling them against a newer version of glibc and breaking binary compatibility with older ones.

    Yeah I know, it's a mess, the transition from 1.8 to 9 has caused all sorts of little headaches like this, which is why JRuby 10 has jumped way forward to Java 21. I can help patch this up though and it won't be a problem in the future.

  11. byroot commented on Sep 18, 2025

    @byroot
    Member

    but I can help in a while or tomorrow

    I'm going to ship the IndexOutOfBoundsException today, given it's the issue at hand.

    However a fix for Unable to find java.base/java.nio.Buffer.checkIndex would indeed be welcome, even though it's never supposed to reach that codepath.

  12. byroot commented on Sep 18, 2025

    @byroot
    Member

    2.14.1 is out with the fix.

  13. sl0thentr0py commented on Sep 18, 2025

    @sl0thentr0py
    Author

    can confirm the issue is fixed, thank you for the quick release!

  14. headius commented on Sep 18, 2025

    @headius
    Contributor

    Thank you @samyron for the patch. I'll fix the build to avoid the other issue in the future.

  15. headius commented on Sep 18, 2025

    @headius
    Contributor

    And thank you @byroot for the quick release!

  16. headius commented on Sep 20, 2025

    @headius
    Contributor

    Now that I'm "in the office" and not on my phone I realize that other warning is not what I thought it was. That is just a warning that rspec emits when it's trying to parse a Java exception and it doesn't know how to display the failing Java source line:

    [] json $ cat npe_spec.rb 
    describe "spec that raises NPE" do
      it "breaks stack analysis" do
        java.lang.System.getProperty(nil)
      end
    end
    
    [] json $ rspec npe_spec.rb
    Ignoring resolv-0.6.2 because its extensions are not built. Try: gem pristine resolv --version 0.6.2
    Ignoring resolv-0.6.2 because its extensions are not built. Try: gem pristine resolv --version 0.6.2
    F
    
    Failures:
    
      1) spec that raises NPE breaks stack analysis
         Failure/Error: Unable to find java.lang.System.checkKey(java/lang/System.java to read failed line
         
         Java::JavaLang::NullPointerException:
           key can't be null
         # java.lang.System.checkKey(java/lang/System.java:854)
         # java.lang.System.getProperty(java/lang/System.java:730)
         # java.lang.reflect.Method.invoke(java/lang/reflect/Method.java:498)
         # RUBY.<main>(/Users/headius/work/json/npe_spec.rb:3)
         # java.lang.invoke.MethodHandle.invokeWithArguments(java/lang/invoke/MethodHandle.java:627)
    

    There's no bug in json.

    I did go ahead and modify the build to guarantee it always builds for Java 8/1.8 using the --release flag when it's available, as part of a few other build tweaks in #866. We haven't actually seen that problem yet, but if releases start getting built with JDK versions newer than 8, this is he the way to avoid it.

  17. changed the title [-]Unable to find java.base/java.nio.Buffer.checkIndex[/-] [+]IndexOutOfBoundsException during SWAR string encoding[/+] on Sep 20, 2025
  18. headius commented on Sep 20, 2025

    @headius
    Contributor

    Updated subject to reflect the actual issue and not the rspec stumble.

  19. etiennebarrie commented on Oct 6, 2025

    @etiennebarrie
    Contributor

    Just FYI I saw that selenium-webdriver has shipped a new version that adds a version requirement because of this bug. It seems like their CI hadn't tested 2.15.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions