Generated JS in Google's Mobile Talkgadget

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Dominik

    Generated JS in Google's Mobile Talkgadget

    Hi there,

    I am investigating a browser compatibility issue with Google' mobile
    talk gadget (http://talkgadget.google.com/talkgadget/m). Please
    compare my posting on: http://www.google.com/support/forum/...6caeb020&hl=en
    -
    After checking the js sources that are imported, I came across this
    function

    var ja = function(a) {
    if (/^\s*$/ [x](a)) return c;
    return /^[\],:{}\s\u2028\u2 029]*$/ [x](a[y](/\\["\\\/bfnrtu]/g,
    "@")[y](/"[^"\\\n\r\u2028\ u2029\x00-\x1f\x7f-\x9f]*"|true|false|n ull|-?
    \d+(?:\.\d*)?(? :[eE][+\-]?\d+)?/g, "]")[y](/(?:^|:|,)(?:[\s
    \u2028\u2029]*\[)+/g, ""))
    }

    while it looks like x is assigned to "test" (var ... x = "test" in the
    beginning of that file) and c is assigned to false.
    I haven't seen this particular bit of JS syntax before:
    if (/^\s*$/ [x](a)) return c;
    Can anybody enlighten me what the expression for the condition
    resolves to? The regexp is clear, means "check if line is only
    whitespace or empty", but the rest is mysterious. For example, why is
    there no logical operator? Or is the regexp applied to the [x](a) ?!?

    It'd be great if anybody could point me to a piece of language
    specification that clarifies this bit.

    After all, it might also be that my vision is blurred and I am
    completely missing something simple. In any case, thanks for your
    help.

    Dominik
  • Thomas 'PointedEars' Lahn

    #2
    Re: Generated JS in Google's Mobile Talkgadget

    Dominik wrote:
    var ja = function(a) {
    if (/^\s*$/ [x](a)) return c;
    [...]
    I haven't seen this particular bit of JS syntax before:
    [...]
    Can anybody enlighten me what the expression for the condition
    resolves to? The regexp is clear, means "check if line is only
    whitespace or empty", but the rest is mysterious. For example, why is
    there no logical operator?
    There does not need to be a logical operator in the parameter of an `if'
    statement; the parameter itself is regarded a boolean expression and
    implicitly type-converted to boolean if it isn't boolean already. See the
    ECMAScript Language Specification, Edition 3 Final (ES3F), section 12.5.
    Or is the regexp applied to the [x](a) ?!?
    Your `?' key is borken.

    Following the syntax rules defined in ES3F, /.../ is a reference to a RegExp
    object. Like any other object, it has properties which can be accessed
    using the dot notation *and* bracket notation property accessor:

    /^\s*$/ [x] === (/^\s*$/)[x] === /^\s*$/[x]

    If

    /^\s*$/ [x](a)

    works, we have to assume that `x' stores the name of a property that refers
    to a callable object (the name of a method), and that `(a)' is the argument
    list of that method call. To show the precedence:

    ((/^\s*$/)[x])(a)

    What this expression resolves to would be impossible to say until the values
    of `x' and `a' were known, and maybe not even then because `x' might store
    the name of a host-defined or user-defined property.

    Possibility: x === "test" and `a' stores an arbitrary string value that is
    being matched against. Then /^\s*$/ [x](a), which would be equivalent to
    /^\s*$/.test(a), would return `true' if `a' was convertible to the empty
    string or its converted value consisted only of whitespace, and `false'
    otherwise; however, !/\S/.test(a) would be more efficient, then.


    HTH

    PointedEars
    --
    var bugRiddenCrashP ronePieceOfJunk = (
    navigator.userA gent.indexOf('M SIE 5') != -1
    && navigator.userA gent.indexOf('M ac') != -1
    ) // Plone, register_functi on.js:16

    Comment

    • Dominik

      #3
      Re: Generated JS in Google's Mobile Talkgadget

      Hi Thomas,
      /^\s*$/ [x] === (/^\s*$/)[x] === /^\s*$/[x]
      Thanks for your excellent analysis! I think it was the space between
      the regexp and the [ that confused me. Your precedence analysis
      explained that this syntax means accessing the properties of the
      regexp reference, not accessing a global property.

      Unfortunately, I'm kind-of stuck at another one:
      if (d) / ^\ //[x](e)||(e=b.f[y](/\/?[^\/]*$/,"/"+e))
      ^^^^^^^^^^^^^^^ ^^^^^ <- especially this first part.

      What would the regexp match, would it ever match? Do spaces have to be
      escaped if you want to match against them, or in other words, why is
      there a non-escaped space and an escaped one? And what is it with that
      double slash before the [x]?

      Thanks in advance for taking a look at it,
      best regards,

      Dominik

      Comment

      • Dominik

        #4
        Re: Generated JS in Google's Mobile Talkgadget

        if (d) / ^\ //[x](e)||(e=b.f[y](/\/?[^\/]*$/,"/"+e))

        I've narrowed it down a little, and my question now boils down to, is
        something like this:
        if (1) /a/.test("a");
        strictly ECMAScript (262 3rd Edition) compatible? I could find a
        production for this so far, looking at the ECMAScript grammar. Or is
        this only allowed by any relaxed specification?

        Dominik

        Comment

        • Thomas 'PointedEars' Lahn

          #5
          Re: Generated JS in Google's Mobile Talkgadget

          Dominik wrote:
          >if (d) / ^\ //[x](e)||(e=b.f[y](/\/?[^\/]*$/,"/"+e))
          >
          I've narrowed it down a little, and my question now boils down to, is
          something like this:
          if (1) /a/.test("a");
          strictly ECMAScript (262 3rd Edition) compatible?
          Yes, of course. If `test' was not modified it would be rather pointless,
          but it fits the production

          IfStatement ::
          if ( Expression ) Statement

          whereas `Statement' would produce a CallExpression here:

          Statement ::
          ExpressionState ment

          ExpressionState ment ::
          ExpressionState ment

          ExpressionState ment ::
          [lookahead ∉ {{, function}] Expression ;

          Expression ::
          AssignmentExpre ssion

          ...

          LeftHandSideExp ression ::
          CallExpression

          CallExpression ::
          CallExpression Arguments

          Arguments ::
          ( ArgumentList )

          ArgumentList ::
          AssignmentExpre ssion

          aso.
          I could find a production for this so far, looking at the ECMAScript
          grammar.
          Did you mean you could *not*?
          Or is this only allowed by any relaxed specification?
          No, the Block statement is not mandatory; see ES3F, 12.5.

          However, semantics can change if you don't use it. So it is recommended
          to use it, with rare (and inevitable) exceptions. That would appear to be
          /the/ code style recommendation for all the languages of the C family.


          PointedEars
          --
          Use any version of Microsoft Frontpage to create your site.
          (This won't prevent people from viewing your source, but no one
          will want to steal it.)
          -- from <http://www.vortex-webdesign.com/help/hidesource.htm>

          Comment

          • Dominik

            #6
            Re: Generated JS in Google's Mobile Talkgadget

            Hi Thomas,
            I've narrowed it down a little, and my question now boils down to, is
            something like this:
            if (1) /a/.test("a");
            strictly ECMAScript (262 3rd Edition) compatible?
            >
            Yes, of course.  If `test' was not modified it would be rather pointless,
            but it fits the production
            >
              IfStatement ::
                if ( Expression ) Statement
            >
            whereas `Statement' would produce a CallExpression here:
            Thanks for your analysis. One question remains, how would we
            ultimately get to the RegularExpressi onLiteral?

            We have:

            CallExpression :
            MemberExpressio n Arguments
            CallExpression Arguments
            CallExpression [ Expression ]
            CallExpression . Identifier

            I understand that /a/.test("a") would fit the "MemberExpressi on
            Arguments" rule here, because:

            MemberExpressio n :
            PrimaryExpressi on
            FunctionExpress ion
            MemberExpressio n [ Expression ]
            MemberExpressio n . Identifier
            new MemberExpressio n Arguments

            So first, we take the 4th production: MemberExpressio n.Identifier, and
            the I would say "PrimaryExpress ion" for the remaining /a/. But how do
            we get from PrimaryExpressi on to RegularExpressi onLiteral? Would our
            bridge be what is described in

            "7.8.5 RegularExpressi onLiterals
            A regular expression literal is an input element that is converted to
            a RegExp object (section 15.10)
            when it is scanned." ?

            Or is there another production to get there just from the pure grammar
            specification?

            Regards,

            Dominik

            Comment

            • Thomas 'PointedEars' Lahn

              #7
              Re: Generated JS in Google's Mobile Talkgadget

              Dominik wrote:
              Hi Thomas,
              Hello. Please provide one attribution line per quotation level instead.
              >>[...] is something like this:
              >>if (1) /a/.test("a");
              >>strictly ECMAScript (262 3rd Edition) compatible?
              >Yes, of course. If `test' was not modified it would be rather pointless,
              >but it fits the production
              >>
              > IfStatement ::
              > if ( Expression ) Statement
              >>
              >whereas `Statement' would produce a CallExpression here:
              >
              Thanks for your analysis. One question remains, how would we
              ultimately get to the RegularExpressi onLiteral?
              >
              We have:
              >
              CallExpression :
              MemberExpressio n Arguments
              CallExpression Arguments
              CallExpression [ Expression ]
              CallExpression . Identifier
              >
              I understand that /a/.test("a") would fit the "MemberExpressi on
              Arguments" rule here, because:
              >
              MemberExpressio n :
              PrimaryExpressi on
              FunctionExpress ion
              MemberExpressio n [ Expression ]
              MemberExpressio n . Identifier
              new MemberExpressio n Arguments
              >
              So first, we take the 4th production: MemberExpressio n.Identifier, and
              the I would say "PrimaryExpress ion" for the remaining /a/. But how do
              we get from PrimaryExpressi on to RegularExpressi onLiteral?
              To understand from grammars in (A)BNFs how a language token can be produced
              it is a good idea to resolve the productions from bottom to top instead of
              vice-versa. IOW, the better approach is to look for productions by which
              RegularExpressi onLiteral can be produced, then work your way "upwards" to
              find out by which productions the "parent" production can be produced.

              However, to spare you the search here, the InputElementReg Exp goal symbol
              which this boils down to is orphaned in the grammar, indeed. Section 7,
              "Lexical Conventions", appears to explain why; it also points out that a
              standalone RegExp literal is not safe per se (which I found rather
              surprising, but it does make sense).


              PointedEars
              --
              Prototype.js was written by people who don't know javascript for people
              who don't know javascript. People who don't know javascript are not
              the best source of advice on designing systems that use javascript.
              -- Richard Cornford, cljs, <f806at$ail$1$8 300dec7@news.de mon.co.uk>

              Comment

              • Dominik

                #8
                Re: Generated JS in Google's Mobile Talkgadget

                Hi Thomas,

                thanks for your reply and poiting out section 7.

                Thomas 'PointedEars' Lahn wrote:
                However, to spare you the search here, the InputElementReg Exp goal symbol
                which this boils down to is orphaned in the grammar, indeed.  Section 7,
                "Lexical Conventions", appears to explain why; it also points out that a
                standalone RegExp literal is not safe per se (which I found rather
                surprising, but it does make sense).
                To my view, it's not really orphaned. In that sense InputElementDiv
                would be orphaned, too. Section 7, that you are referring to, explains
                that both symbols are used as goal symbols during the lexical analysis
                depending on the context; the context being defined by the
                *syntactical* grammar. InputElementDiv in cases where a division
                punctuator is allowed and expected, InputElementReg Exp for the
                remaining cases.
                We have a production from InputElementReg Exp to
                RegularExpressi onLiteral for the lexical analysis. So in the lexical
                analysis, regular expressions are detected and properly tokenized. But
                the RegularExpressi onLiteral symbol is only used for the lexical
                analysis. There is no direct way of producing anything equivalent to
                the RegularExpressi onLiteral when using the syntactical grammar. What
                comes closest in the syntactical grammar would be what is described in
                A.7 Regular Expressions, more precisely the Pattern symbol. However,
                in the syntactical grammar, we don't have a production that would get
                us to Pattern. Also, thanks to your help, I'm seeing it a bit more
                clearly now. My earlier question pointed at
                >"7.8.5 RegularExpressi onLiterals
                >A regular expression literal is an input element that is converted to
                >a RegExp object (section 15.10) when it is scanned."
                This clause would according to my understanding still be the only way
                to explain how we can have regular expressions in the syntactical
                analysis, and that is - by replacing them with something else. If we
                assume that /...someRegExp.. ./ gets converted to
                new RegExp("...some RegExp...")
                then we can get from
                CallExpression
                to
                MemberExpressio n
                , then to
                new MemberExpressio n Arguments

                which matches
                new Regexp("...some RegExp...")

                (I know, the top down approach again, hope you bear with me. I'm using
                it just for the purpose of explaining my point)

                To conclude, 7.8.5 seems to me the only way to explain that the
                initial example
                if (1) /a/.test("a");
                is valid according to the ECMAScript grammar. Or in other words,
                during the lexical analysis, after the closing bracket of the if
                statement, the scanner must be in a mode where it's looking to fulfil
                a InputElementReg Exp goal symbol.

                Again, thank you for giving some important clues that helped me to
                understand this issue,
                best regards,

                Dominik

                Comment

                Working...