Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Master: fopen with directories makes fseek throw #52

Open
mhenschel opened this issue Sep 11, 2014 · 12 comments
Open

Master: fopen with directories makes fseek throw #52

mhenschel opened this issue Sep 11, 2014 · 12 comments

Comments

@mhenschel
Copy link

I created an embedded in memory backing store containing a directory with some files in it. In my C++ code I accidentally tried to fopen the directory instead of a file. The fopen works but when I try to seek to the end of the opened file (to get the file size by calling ftell) there is a null reference exception in
"PlayerKernel.lseekImpl"

For example:

  1. This is the directory structure
    /directory/file.txt

This is the code that leads to the bug FILE* file=fopen("directory"); if (file) { fseek(File, 0, SEEK_END); }
I think opening a directory might be undefined behavior in C++ but throwing exceptions into native C code in an fseek call is a problem. IMHO a reasonable thing to do would be to let the fopen call just fail for directories.

@vpmedia
Copy link
Member

vpmedia commented Sep 11, 2014

Hi,
Can you make a compact example with a makefile for testing the issue?
Also please post which version of the SDK are you using, if the problem is specific for that.
And a full flash player trace log is also helpful..

@vpmedia
Copy link
Member

vpmedia commented Sep 11, 2014

I've checked crossbridge \ posix \ PlayerKernel.as for a glance, but I don't see any trivial problems so it would be great if you could help fixing the problem / maybe sending a pull request.

@mhenschel
Copy link
Author

Hi. I'll try my best. May be I can modify the example 07 to show the problem. I also had a look at PlayerKernel.as and the only place where a null ref exception might happen was seeking relative to the end of a file. In this case the length of the array for the file content is accessed to get the file length. If the array doesn't exist it would crash.

@vpmedia
Copy link
Member

vpmedia commented Sep 12, 2014

I think that method is protected against null refs. at the beginning.
A full flash player error trace log would really help ; )

private function lseekImpl(fd:int, offset:int, whence:int, 
            errnoPtr:int):* {
        var fdentry:FileHandle = CModule.vfs.getFileHandleFromFileDescriptor(fd)
        if (!fdentry) {
            CModule.write32(errnoPtr, KernelConstants.EBADF)
            return null
        } else if (fdentry.callback) {
            CModule.write32(errnoPtr, KernelConstants.ESPIPE)
            return null
...

Can you point to the line where it thrown the excptn.?

@vpmedia vpmedia changed the title fopen with directories makes fseek throw Master: fopen with directories makes fseek throw Sep 12, 2014
@mhenschel
Copy link
Author

Hi. I have a repro case and a trace log. How can I get the exact line number of the exception being thrown? That would be really helpful. Do I have to build a debug version then? Here is the trace log:

DefaultPreloader::created CModule::startAsync: [object Console] CModule::start: [object Console],,,true TypeError: Error #1009: Cannot access a property or method of a null object reference. at com.adobe.flascc.kernel::PlayerKernel/lseekImpl() at com.adobe.flascc.kernel::PlayerKernel/lseek() at global/C_Run::F___sys_lseek() at global/C_Run::F_lseek() at global/C_Run::F___sseek() at global/C_Run::F__sseek() at global/C_Run::F__fseeko() at global/C_Run::F_fseek() at global/C_Run::F_main() at global/C_Run::F__start1() at com.adobe.flascc::CModule$/callI() at com.adobe.flascc::CModule$/start() at com.adobe.flascc::CModule$/startAsync() at com.adobe.flascc::Console/onComplete() at flash.events::EventDispatcher/dispatchEventFunction() at flash.events::EventDispatcher/dispatchEvent() at com.adobe.flascc.vfs::HTTPBackingStore/startNewFile() at com.adobe.flascc.vfs::HTTPBackingStore/startNewDownload() at com.adobe.flascc.vfs::HTTPBackingStore/onComplete() at flash.events::EventDispatcher/dispatchEventFunction() at flash.events::EventDispatcher/dispatchEvent() at flash.net::URLLoader/onComplete()

For a repro case I slightly modified sample 07.

@vpmedia
Copy link
Member

vpmedia commented Sep 12, 2014

Thats enough, it's possible that it is tricky to get the line number, since you are using a CrossBridge ABCs. Maybe with FlashDeBugger (FDB) but i'm unsure.
Anyway the log helped a bit, also a second verification helped, so I think the problem is with:

 newpos = fdentry.bytes.length + offset

where fdentry.bytes is NULL.
maybe it should be guarded against your use case, I'm not sure yet, what operation would be the appropriate (it's pretty low level for me : ).

@vpmedia
Copy link
Member

vpmedia commented Sep 12, 2014

Do you think this would be good enough?

newpos = fdentry.bytes ? fdentry.bytes.length + offset : offset 

or when there are no bytes it should exit like:

 CModule.write32(errnoPtr, KernelConstants.EINVAL)
 return null

?

I'm not really familiar with the C file I/O internals, since coming from an AS3 background ...

@mhenschel
Copy link
Author

I think it's wrong in the first place that fopen succeeds with a directory. It doesn't make much sense to open a file handle for a directory because you cannot do anything with it. The best solution would be not to create a file handle for directories. I don't know where the code is for that but I can try to find it.

@mhenschel
Copy link
Author

I'm not sure about how freebsd treats open calls on directories. So I'll first check what's supposed to happen with directories first. I'll report back ...

@JoeDupuis
Copy link
Member

I created this repo https://github.com/twistedjoe/testFopen

You can use it with :

Native OSX and Cygwin

make native && ./native 

Flash CLI build (still using the real filesystem)

export PATH=<path to crossbrdige /usr/bin>:$PATH
make flash && ./flash

SWF with embedvfs

export PATH=<path to crossbrdige /usr/bin>:$PATH
CROSSBRIDGE=<path to crossbridge> make vfs  
*double click the vfs.swf file*

Native output:

Mode: 'r'
File mode r open successfully
Seek don't crash
directoryTest mode r open successfully
Seek don't crash    



Mode: 'w'
File mode w open successfully
Seek don't crash
directoryTest mode w pFile==NULL    



Unexisting directory :
unexistringDir mode r pFile==NULL
unexistringDir mode w open successfully
Seek don't crash

Flash cli output

File mode r open successfully
Seek don't crash
directoryTest mode r open successfully
Seek don't crash    



Mode: 'w'
File mode w open successfully
Seek don't crash
directoryTest mode w pFile==NULL    



Unexisting directory :
unexistringDir mode r open successfully
Seek don't crash
unexistringDir mode w open successfully
Seek don't crash
Exit::exit: 0

VFS.swf output

Mode: 'r'
File mode r open successfully
Seek don't crash
directoryTest mode r open successfully

Then it crash with:

TypeError: Error #1009: Cannot access a property or method of a null object reference.
at com.adobe.flascc.kernel::PlayerKernel/lseekImpl()
at com.adobe.flascc.kernel::PlayerKernel/lseek()
at global/C_Run::F___sys_lseek()
at global/C_Run::F___sseek()
at global/C_Run::F__sseek()
at global/C_Run::F__fseeko()
at global/C_Run::F_fseek()
at global/C_Run::F_main()
at global/C_Run::F__start1()
at com.adobe.flascc::CModule$/callI()
at com.adobe.flascc::CModule$/start()
at com.adobe.flascc::CModule$/startAsync()
at com.adobe.flascc::Console/init()
at com.adobe.flascc::Console()
at com.adobe.flascc.preloader::DefaultPreloader/onPreloaderComplete()

Since even the native OSX build seems happy to open a directory in read mode, I don't think it would be necessary to handle this. It does not seem like a bug. Just undefined behaviour in the standard.

@vpmedia
Copy link
Member

vpmedia commented Sep 13, 2014

@mhenschel Can you please repost the following issue report, since I have deleted the sourceforge forum.
" Hi, I'm having issues with exceptions thrown from flash++ wrappers. Exceptions inside... " - If still relevant.

@mhenschel
Copy link
Author

OK. I checked my FreeBSD machine. fopen works with directories and seeking simply seems do do nothing. So I think your fix will be sufficient. Thanks for the reminder about the forum post.

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

No branches or pull requests

3 participants