php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #22882 shmop_read should return string length, not shm segment size
Submitted: 2003-03-25 14:42 UTC Modified: 2003-03-25 16:10 UTC
From: discussion at vodopivec dot com Assigned:
Status: Not a bug Package: Strings related
PHP Version: 4.3.1 OS: Linux
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: discussion at vodopivec dot com
New email:
PHP Version: OS:

 

 [2003-03-25 14:42 UTC] discussion at vodopivec dot com
My opinion is that shmop_read function has wrong behaviour, returning 'count' parameter as the length of the string, instead of real length of the string, up to the terminating zero.
 
This should be easy to fix, in fact I already did, but 
someone should apply this patch - in shmop_read, 
instead of
 
RETURN_STRINGL(return_string, bytes, 0);
 
you can use 
 
RETURN_STRINGL(return_string, strlen(return_string), 0);
 
Below is the php code that demonstrates this problem.
 
Thanks,
 
Mario.
 
<?php
 
  $buffer = "12345";
 
  // Create 100 byte shared memory block with system id if 0xff3
  $shm_id = shmop_open(0xff3, "c", 0644, 100);
  if(!$shm_id) {
    echo "Couldn't create shared memory segment\n";
  }
 
  // Get shared memory block's size
  $shm_size = shmop_size($shm_id);
  echo "SHM Block Size: ".$shm_size. " has been created.\n";
 
  // Lets write a test string into shared memory
  $shm_bytes_written = shmop_write($shm_id, $buffer, 0);
  if($shm_bytes_written != strlen($buffer)) {
    echo "Couldn't write the entire length of data\n";
  }
 
  // Now lets read the string back
  $my_string = shmop_read($shm_id, 0, $shm_size);
  if(!$my_string) {
    echo "Couldn't read from shared memory block\n";
  }
  echo "The data inside shared memory was: ".$my_string."<br>\n";
 
  if ($my_string != $buffer)
  {
    print "This is where it doesn't make sense"."<br>\n";
    print "buffer len = ".strlen($buffer)."<br>\n";
    print "my string len = ".strlen($my_string)."<br>\n";
  }
 
  //Now lets delete the block and close the shared memory segment
  if(!shmop_delete($shm_id)) {
    echo "Couldn't mark shared memory block for deletion.";
  }
  else
    echo "Deleted shm block";
 
  shmop_close($shm_id);
 
?>
 

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2003-03-25 14:50 UTC] wez@php.net
This would break binary data stored in the shm segment; we will not apply this patch.
 [2003-03-25 14:59 UTC] discussion at vodopivec dot com
You have the point and I agree; But how about having a separate function for this purpose, like shmop_read_string?

The submitted php script demonstrates this problem, and although not impossible, it's extremely difficult to deal with this.

After all, it doesn't make sense to write, then read shared memory, compare values and get false result.
 [2003-03-25 15:17 UTC] iliaa@php.net
Ideally you should already know how much data you intend to read and would only read that many bytes rather then the entire segment.
If that is now easily possible you could prefix your data with a 10 byte 'buffer' containing 0000000012 for example, which would indicate that the data following this header is 12 bytes long.
 [2003-03-25 15:35 UTC] discussion at vodopivec dot com
I like your workaround, but that's still a workaround, isn't it? And most people wouldn't think of that.

I would still prefer having separate functions for strings, php is supposed to be easy to use. Why not, it's not like it involves a lot of additional work?
 [2003-03-25 15:56 UTC] iliaa@php.net
What you are asking for is a hack, shared memory segments may contain anything, including binary data. Which means just reading until 1st \0 may result in partiual data being read and that is bad.
My solution was just one solution, I see at least two other possible approaches to the same problem.
For example doing: 
$my_string = rtrim($my_string);
would also remove the invisible \0 padding and make the string size 5 characters.
 [2003-03-25 16:10 UTC] discussion at vodopivec dot com
You're right, rtrim is an elegant solution, once you figure what kind of problem you have...

Maybe this should just be mentioned somewhere in shmop help files.

Thank you for your prompt replies.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Jun 25 18:01:32 2024 UTC