Whitespace-only strings somehow getting corrupted

已查看 4 次
跳至第一个未读帖子

Ian Beck

未读,
2010年8月13日 13:45:462010/8/13
收件人 JSCocoa
Hey there,

First, just a quick problem with the TestsRunner application: you're
using the NSApplicationDelegate protocol, which is a 10.6-only
feature, but the Base SDK is set to be 10.5.

The actual problem I'm having: when I pass an NSString that consists
entirely of whitespace from Objective-C into Javascript I'm getting
something strange on the Javascript side. Logging it or appending it
to an existing string evaluates it as '0'. I constructed a quick test
with TestsRunner to showcase the problem:

TestsRunner/ApplicationController.m Line 899:

@interface MRTestWhitespace : NSObject
@end

@implementation MRTestWhitespace

- (NSString *)fetchLinebreak {
return @"\n";
}
- (NSString *)fetchTab {
return @" ";
}
- (NSString *)fetchSpaces {
return @" ";
}

@end

And I added a quick new test file (called Tests/56 Test Whitespace.js,
not that the name matters):

// Test what we get for whitespace

var object = MRTestWhitespace.alloc.init.autorelease;

var linebreak = object.fetchLinebreak;

log('Linebreak: `' + linebreak + '`');
log('Tab: `' + object.fetchTab + '`');
log('Four Spaces: `' + object.fetchSpaces + '`');

if (linebreak) {
log('linebreak evaluates as true');
} else {
log('linebreak evaluates as false');
}

log('className: ' + linebreak.className);

// End test whitespace

Any help you can offer to debug what is going on here is appreciated!
At this point, I'm not sure if the problem is with JSCocoa,
JavascriptCore, or something else altogether.

Ian

Ian Beck

未读,
2010年8月17日 18:55:532010/8/17
收件人 JSCocoa
I've been trying to figure out what the heck is going wrong on my own,
and here is what I've discovered so far:

- I'm working with the following object:
context.textPreferences.tabString, which in Objective-C returns an
NSString that contains a tab character

- the jsCocoaObject_getProperty call for tabString properly returns a
JSValueRef with a private object that is an NSString whose contents
are a tab character

- Somewhere between this getting returned and Javascript figuring out
how to convert the boxed object, it gets trashed so that when I do
this in Javascript:

log('linebreak: ' + context.textPreferences.tabString);

I get this in the Console: 'linebreak: 0'.

Unfortunately, I do not know what happens after
jsCocoaObject_getProperty returns, so I'm not sure what's happening to
the JSValueRef that it returns.

So far I've been going off of the description of what happens
internally here to give me an idea about where to look for problems:

http://code.google.com/p/jscocoa/wiki/SampleBridgeEvaluation

But I'll need some hints to figure out exactly what is calling
jsObject_getProperty. Anyone know what is going on behind the scenes
here? Thanks!

Ian

Gus Mueller

未读,
2010年8月17日 23:12:072010/8/17
收件人 jsc...@googlegroups.com
I don't have an answer for you- but maybe it has something to do with the auto method calling stuff? I've got that turned off in JSTalk, and your string methods return the right values.

-gus

> --
> JSCocoa: http://inexdo.com/JSCocoa
> Source: http://github.com/parmanoir/jscocoa/tree/master
> Docs: http://code.google.com/p/jscocoa/
> Group: http://groups.google.com/group/jscocoa
> Unsubscribe: jscocoa+u...@googlegroups.com
>


--

August 'Gus' Mueller
Flying Meat Inc.
http://flyingmeat.com/

Ian Beck

未读,
2010年8月18日 12:40:282010/8/18
收件人 JSCocoa
Hey Gus,

Thanks for the suggestion! Switching autoCall off and using
context.textPreferences().tabString() oddly gets me the same response
as before. What revision of JSCocoa are you using? I poked around in
the JSTalk source, but there weren't any explicit submodules or
anything (looked like it just assumed the jscocoa project would be
cloned in a subdirectory).

I'll go through the JSTalk source and see if there's any other
differences I can spot and test.

Ian

Gus Mueller

未读,
2010年8月18日 13:25:132010/8/18
收件人 jsc...@googlegroups.com
On Aug 18, 2010, at 9:40 AM, Ian Beck wrote:

> Thanks for the suggestion! Switching autoCall off and using
> context.textPreferences().tabString() oddly gets me the same response
> as before. What revision of JSCocoa are you using?

Whatever the latest is. I recently screwed up our module support, so you'll just have to checkout the source.

-gus

Ian Beck

未读,
2010年8月18日 13:55:132010/8/18
收件人 JSCocoa
Hey Gus,

Mimicking what you were doing in JSTalk wasn't working for me, so I
tried the following:

1) Cloned the latest JSCocoa in the latest JSTalk source
2) Modified JSTDocumentController.m, adding this to the end:

@interface MRTestWhitespace : NSObject
@end
@implementation MRTestWhitespace
- (NSString *)fetchLinebreak {
return @"\n";
}
- (NSString *)fetchTab {
return @" ";
}
- (NSString *)fetchSpaces {
return @" ";
}
@end

3) Built JSTalk
4) Launched JSTalk Editor and executed this code:

var tester = [[MRTestWhitespace alloc] init];

log('linebreak: `' + tester.fetchLinebreak() + '`');
log('tab: `' + tester.fetchTab() + '`');
log('spaces: `' + tester.fetchSpaces() + '`');

5) In the Console, I got this:

linebreak: `0`
tab: `0`
spaces: `0`

Which is exhibiting the same issues that I've been having with the
JSCocoa TestRunner and within my test application plugins. If you
have time, would you mind replicating this test on your end? I'm
really curious if there's something specifically wrong on my end or if
there is indeed a bug in JSCocoa somewhere that's causing this
problem.

Ian

Ian Beck

未读,
2010年8月18日 14:17:512010/8/18
收件人 JSCocoa
Hey Gus,

Nevermind! No need for you to test anything, because I located the
cause of the problem. There's some logic that checks strings to see
if they are just a number and returns the number if so, and it was
improperly setup to ignore whitespace. I'll fix the issue and send
Patrick a pull request.

Ian

Gus Mueller

未读,
2010年8月18日 14:26:262010/8/18
收件人 jsc...@googlegroups.com
On Aug 18, 2010, at 11:17 AM, Ian Beck wrote:

> Nevermind! No need for you to test anything, because I located the
> cause of the problem. There's some logic that checks strings to see
> if they are just a number and returns the number if so, and it was
> improperly setup to ignore whitespace

Ugh, that's sounds horrible :)

Where in the code is this? And I'm wondering if it can be turned on/off?

Ian Beck

未读,
2010年8月18日 14:30:052010/8/18
收件人 JSCocoa
Hey Gus,

Here's the fix:

http://github.com/onecrayon/jscocoa/commit/34800d367fa024d64ae3decad042997e2723b834

I don't think it can currently be turned off, but if the comment
attached to the function is correct it might be specific to autoCall
(which would explain why it wasn't triggering for you, although I'm
not sure why turning off autoCall on my end didn't help).

Ian

Patrick Geiller

未读,
2010年8月18日 14:40:342010/8/18
收件人 jsc...@googlegroups.com
Thanks for the fix Ian !

Gus : the conversion happens only on request during valueOf().
In Javascript, '4'*2 = 8.
Without that conversion, [NSString stringWithString:4]*2 fails. With it, NSString emulates standard Javascript behaviour. It is not dependent on autocall or anything else.

But it you want a switch to turn it off, I'm happy to oblige :)

Patrick Geiller

未读,
2010年8月18日 15:04:032010/8/18
收件人 jsc...@googlegroups.com
if the comment attached to the function is correct

Well, ... it isn't.

Fixed.

//
// valueOf : from a boxed ObjC object, returns a primitive javascript value (number or string) 
//  that JavascriptCore can use in expressions (eg boxedObject + 'this', boxedObject < 4)
//
//  The returned value is temporary and does not affect the boxed object.
//

The conversion NSString->number happens @ JSCocoaController.m:3115 .

Gus Mueller

未读,
2010年8月18日 17:00:532010/8/18
收件人 jsc...@googlegroups.com
On Aug 18, 2010, at 11:40 AM, Patrick Geiller wrote:

> Gus : the conversion happens only on request during valueOf().
> In Javascript, '4'*2 = 8.
> Without that conversion, [NSString stringWithString:4]*2 fails. With it, NSString emulates standard Javascript behaviour. It is not dependent on autocall or anything else.
>
> But it you want a switch to turn it off, I'm happy to oblige :)

If it's standard JS behavior- let's keep it in. It seems to do the right thing for '4' + 3, ('43'), but then gives 12 for '4'*3. Odd. JS. Whatever :)

回复全部
回复作者
转发
0 个新帖子