On Wed, Sep 16, 2026 at 10:15 AM Mark Thomas <[email protected]> wrote:
>
> On 14/09/2026 22:24, [email protected] wrote:
> > This is an automated email from the ASF dual-hosted git repository.
> >
> > rmaucher pushed a commit to branch main
> > in repository https://gitbox.apache.org/repos/asf/tomcat.git
> >
> >
> > The following commit(s) were added to refs/heads/main by this push:
> >       new 5578eb98c1 Unescape quoted strings
> > 5578eb98c1 is described below
> >
> > commit 5578eb98c185d38f76b03af1994cc515892e2813
> > Author: remm <[email protected]>
> > AuthorDate: Mon Sep 14 23:24:29 2026 +0200
> >
> >      Unescape quoted strings
>
> Which version of JavaCC are you using to generate the parser? I am
> trying to fix an issue around double-decoding with unicode escaped '\'
> and can't seem to recreate the same output given the current jjt file.

Oops. So this is direct editing (which is bad, but it seemed
straightforward). Rationale for the change: the JSON was written
escaped, so expecting to read it back unescaped did not seem
unreasonable.

Rémy

> Mark
>
>
> > ---
> >   java/org/apache/tomcat/util/json/JSONParser.java | 32 
> > ++++++++++++++++++++++--
> >   java/org/apache/tomcat/util/json/JSONParser.jjt  | 32 
> > ++++++++++++++++++++++--
> >   2 files changed, 60 insertions(+), 4 deletions(-)
> >
> > diff --git a/java/org/apache/tomcat/util/json/JSONParser.java 
> > b/java/org/apache/tomcat/util/json/JSONParser.java
> > index c21b0f67f9..88c880e6ee 100644
> > --- a/java/org/apache/tomcat/util/json/JSONParser.java
> > +++ b/java/org/apache/tomcat/util/json/JSONParser.java
> > @@ -75,6 +75,34 @@ public class JSONParser implements JSONParserConstants {
> >           return str.substring(0, pos);
> >       }
> >
> > +    /**
> > +     * Resolve the JSON escape sequences of a string token body (the
> > +     * surrounding quotes are already removed). The token grammar only
> > +     * admits the short escapes: {@code \b}, {@code \f}, {@code \n},
> > +     * {@code \r}, {@code \t}, {@code \/}, {@code \\} and the
> > +     * self-escaped quote character.
> > +     */
> > +    private static String unescape(String value) {
> > +        StringBuilder result = new StringBuilder(value.length());
> > +        for (int i = 0; i < value.length(); i++) {
> > +            char c = value.charAt(i);
> > +            if (c != '\\' || i + 1 >= value.length()) {
> > +                result.append(c);
> > +                continue;
> > +            }
> > +            char next = value.charAt(++i);
> > +            switch (next) {
> > +                case 'b' -> result.append('\b');
> > +                case 'f' -> result.append('\f');
> > +                case 'n' -> result.append('\n');
> > +                case 'r' -> result.append('\r');
> > +                case 't' -> result.append('\t');
> > +                default -> result.append(next);
> > +            }
> > +        }
> > +        return result.toString();
> > +    }
> > +
> >       public void setNativeNumbers(boolean value) {
> >           this.nativeNumbers = value;
> >       }
> > @@ -452,7 +480,7 @@ public class JSONParser implements JSONParserConstants {
> >                   String image = token.image;
> >                   {
> >                       if ("" != null) {
> > -                        return image.substring(1, image.length() - 1);
> > +                        return unescape(image.substring(1, image.length() 
> > - 1));
> >                       }
> >                   }
> >                   break;
> > @@ -481,7 +509,7 @@ public class JSONParser implements JSONParserConstants {
> >                   String image = token.image;
> >                   {
> >                       if ("" != null) {
> > -                        return image.substring(1, image.length() - 1);
> > +                        return unescape(image.substring(1, image.length() 
> > - 1));
> >                       }
> >                   }
> >                   break;
> > diff --git a/java/org/apache/tomcat/util/json/JSONParser.jjt 
> > b/java/org/apache/tomcat/util/json/JSONParser.jjt
> > index 08996d10ab..1726c4cab4 100644
> > --- a/java/org/apache/tomcat/util/json/JSONParser.jjt
> > +++ b/java/org/apache/tomcat/util/json/JSONParser.jjt
> > @@ -106,6 +106,34 @@ public class JSONParser {
> >           return str.substring(0, pos);
> >       }
> >
> > +    /**
> > +     * Resolve the JSON escape sequences of a string token body (the
> > +     * surrounding quotes are already removed). The token grammar only
> > +     * admits the short escapes: {@code \b}, {@code \f}, {@code \n},
> > +     * {@code \r}, {@code \t}, {@code \/}, {@code \\} and the
> > +     * self-escaped quote character.
> > +     */
> > +    private static String unescape(String value) {
> > +        StringBuilder result = new StringBuilder(value.length());
> > +        for (int i = 0; i < value.length(); i++) {
> > +            char c = value.charAt(i);
> > +            if (c != '\\' || i + 1 >= value.length()) {
> > +                result.append(c);
> > +                continue;
> > +            }
> > +            char next = value.charAt(++i);
> > +            switch (next) {
> > +                case 'b' -> result.append('\b');
> > +                case 'f' -> result.append('\f');
> > +                case 'n' -> result.append('\n');
> > +                case 'r' -> result.append('\r');
> > +                case 't' -> result.append('\t');
> > +                default -> result.append(next);
> > +            }
> > +        }
> > +        return result.toString();
> > +    }
> > +
> >       public void setNativeNumbers(boolean value) {
> >           this.nativeNumbers = value;
> >       }
> > @@ -358,7 +386,7 @@ String doubleQuoteString() : {
> >           <STRING_DOUBLE_NONEMPTY>
> >           {
> >               String image = token.image;
> > -            return image.substring(1, image.length() - 1);
> > +            return unescape(image.substring(1, image.length() - 1));
> >           }
> >       )
> >   }
> > @@ -372,7 +400,7 @@ String singleQuoteString() : {
> >           <STRING_SINGLE_NONEMPTY>
> >           {
> >               String image = token.image;
> > -            return image.substring(1, image.length() - 1);
> > +            return unescape(image.substring(1, image.length() - 1));
> >           }
> >       )
> >   }
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: [email protected]
> > For additional commands, e-mail: [email protected]
> >
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
>

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to