php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #42036 fgetc() sets end of the file flag when reading on write only file
Submitted: 2007-07-18 16:48 UTC Modified: 2008-02-09 19:51 UTC
From: kraghuba at in dot ibm dot com Assigned: wez (profile)
Status: Closed Package: Filesystem function related
PHP Version: 5CVS-2007-07-18 (snap) OS: RHEL 5
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: kraghuba at in dot ibm dot com
New email:
PHP Version: OS:

 

 [2007-07-18 16:48 UTC] kraghuba at in dot ibm dot com
Description:
------------
fgetc() sets the end of the file flag to ture when reading from a file which opened in write only mode.

This failure is applicable on php5 and php6

php version:
PHP 6.0.0-dev (cli) (built: Jul 18 2007 20:53:03) (GCOV)
Copyright (c) 1997-2007 The PHP Group
Zend Engine v3.0.0-dev, Copyright (c) 1998-2007 Zend Technologies

&
PHP 5.2.4-dev (cli) (built: Jul 18 2007 20:49:53) (GCOV)
Copyright (c) 1997-2007 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies

OS : RHEL 5
configure setup:
  ./configure --enable-gcov

Reproduce code:
---------------
<?php
  $fp = fopen("test.txt", "w");
  var_dump( fwrite($fp, "Text") );

  // rewind the file pointer to begining
  var_dump( rewind($fp) );
  var_dump( ftell($fp) );
  var_dump( feof($fp) );

  // try to read
  var_dump( fgetc($fp) );
  var_dump( ftell($fp) );
  var_dump( feof($fp) );

  fclose($fp);
  unlink("test.txt");
?>

Expected result:
----------------
output - php5:
--------------
int(4)
bool(true)
int(0)
bool(false)
bool(false)
int(0)
bool(false)

output - php6:
--------------
int(4)
bool(true)
int(0)
bool(false)
bool(false)
int(0)
bool(false)

Actual result:
--------------
output - php5:
--------------
int(4)
bool(true)
int(0)
bool(false)
bool(false)
int(0)
bool(true)

output - php6:
--------------
int(4)
bool(true)
int(0)
bool(false)
string(1) ""
int(0)
bool(true)

output on php6 when run using run-test.php :
int(4)
bool(true)
int(0)
bool(false)
string(1) "?"
int(0)
bool(true)

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2007-07-21 05:55 UTC] kraghuba at in dot ibm dot com
This defect is also applicable to the function fgets().
 [2007-07-23 08:34 UTC] tony2001@php.net
Wez, could you plz comment this?
 [2007-07-23 14:47 UTC] wez@php.net
Without having had time to dig deeper just yet, if you open for write only, you shouldn't expect to be able to read.  This application-level error is reflected as EOF.

So the question becomes, is this behavior different from libc, and did the php behavior change between releases? (I'm not including PHP 6 in that, because it is not released yet)

If the latter, we need to fix it, it not, we probably shouldn't fix it if there's a risk of breaking an app.

I'm leaning towards won't fix; you should open the file as you intend to use it.
 [2007-07-31 12:13 UTC] kraghuba at in dot ibm dot com
I have tried similar stuff on C language and and found that feof doesn't get changed by using fgetc() on file opened in write only mode. The documentation of fgetc() for C says that it returns an int or EOF on end of the file or an *error*. 

I haven't have enough time to look at any other version other than php6 and 5 (:

I think that same thing can be done for php, the application level error should be reported as false and this should be documented. Even other wise if you decide to have the EOF as application level error then it should be documented. 

Sample code that i use for checking it fgetc() on C :
#include <stdio.h>
int main ( void )
{
  FILE *fp;
  char ch;

  fp = fopen("test.txt", "w");
  fwrite("testing", 7, 1, fp);

  rewind(fp);
  printf("\nftell() returns = %d\n", ftell(fp) );
  printf("\nfeof() returns = %s\n", ( feof(fp) ? "true" : "false") );

  // try read
  printf("\nfgets() returns = %d\n", fgetc(fp) );
  printf("\nftell() returns = %d\n", ftell(fp) );
  printf("\nfeof() returns = %s\n", ( feof(fp) ? "true" : "false") );

  fclose(fp);
}

Output:

ftell() returns = 0

feof() returns = false

fgets() returns =-1

ftell() returns = 0

feof() returns = false
 [2007-08-01 10:54 UTC] jani@php.net
Wez, better that you decide. ;)
 [2007-08-09 01:00 UTC] php-bugs at lists dot php dot net
No feedback was provided for this bug for over a week, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
 [2008-02-09 19:51 UTC] felipe@php.net
This bug has been fixed in CVS.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.

The code wasn't checking for EOF.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Dec 27 15:01:29 2024 UTC