Skip to content

SnakePickle.snakeToCamel crashes on keys with leading, trailing, or consecutive underscores #470

@haskiindahouse

Description

@haskiindahouse

Hit this while decoding a JSON payload that contained a "_request_id" field. SnakePickle.snakeToCamel calls x(0) on each segment without checking for empty strings, which throws StringIndexOutOfBoundsException whenever split("_", -1) produces an empty segment — i.e. for any key with leading, trailing, or consecutive underscores.

Reproducer (scala-cli):

//> using scala 3.8.3

@main def repro(): Unit =
  // Same logic as core/src/main/scala/sttp/ai/core/json/SnakePickle.scala (lines 13-14)
  def snakeToCamel(s: String): String =
    val res = s.split("_", -1).map(x => s"${x(0).toUpper}${x.drop(1)}").mkString
    s"${s(0).toLower}${res.drop(1)}"

  snakeToCamel("_type")        // throws
  snakeToCamel("some__key")    // throws
  snakeToCamel("trailing_")    // throws

Output:

java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  at SnakePickle$.snakeToCamel(SnakePickle.scala:14)

Source pointer:

private def snakeToCamel(s: String): String = {
val res = s.split("_", -1).map(x => s"${x(0).toUpper}${x.drop(1)}").mkString

Any OpenAI-style API field whose JSON name starts with _ (private/internal fields are common) will trigger this. Filtering empty segments — s.split("_", -1).filter(_.nonEmpty) — fixes it without changing behaviour for well-formed keys. There's a related but milder issue in camelToSnake where strings starting with an uppercase letter end up with a leading underscore, but that one isn't a crash. Happy to PR both.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions