Warning: preg_replace() [function.preg-replace]: Compilation failed: range out of order in character class at offset 230 in _filefield_paths_replace_path() (line 430 of /modules/filefield_paths/filefield_paths.module).

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

jastraat’s picture

This occurs after removing an image from an image field and then uploading a new one with a new name.

jastraat’s picture

It also has the rather devastating effect of clearing all text fields within the node being saved.

jastraat’s picture

Title: preg_replace(): Compilation failed: range out of order in character class at offset 230 in _filefield_paths_replace_path() » All text-based fields wiped empty after replacing a file in a node and saving.
jastraat’s picture

Priority: Normal » Major

This error is entirely related to the new function introduced in the following commit: http://drupalcode.org/project/filefield_paths.git/commit/0a3908f
This commit didn't reference an issue, so I'm afraid I don't even understand what problem it's trying to address. The PHP error generated is unfortunately destroying all text content within the node however, so this rather critical.

Deciphered’s picture

Status: Active » Postponed (maintainer needs more info)

I hate to have to point out the obvious, but if you use a beta or a dev version of a module in a production environment this thing may happen. It's not a good thing, but if all issues are ever to be fixed it requires people to find the issues, which you have and you have also done the appropriate thing to report the issue.

There's a good chance the issue no longer exists, but I would ask you if you can to try the latest version (or preferably the version that will come out in the next 12 hours) and confirm whether it still exists and provide me with as much information on reproducing the issues as possible. My own testing has been unable to reproduce this issue so far.

Cheers,
Deciphered.

jastraat’s picture

Version: 7.x-1.0-beta1 » 7.x-1.0-beta3
Status: Postponed (maintainer needs more info) » Active

This is still a problem in the beta3 version of the module. I imagine it's the same issue that is being seen in Drupal 6 here: http://drupal.org/node/723784

Error message:
Warning: preg_replace() [function.preg-replace]: Compilation failed: range out of order in character class at offset 224 in _filefield_paths_replace_path() (line 299 of /public_html/sites/pages.wustl.edu/modules/filefield_paths/filefield_paths.module).
Warning: preg_replace() [function.preg-replace]: Compilation failed: range out of order in character class at offset 224 in _filefield_paths_replace_path() (line 299 of /public_html/sites/pages.wustl.edu/modules/filefield_paths/filefield_paths.module).

I have an image field in a content type that uses this module to create file path and file name from tokens including a custom token. The content type also has a text field. The error only occurs when the text field has content and I remove an image and replace it in the same edit screen. If I comment out the call to _filefield_paths_replace_path, everything works fine with the custom token.

I've done some testing, and I believe the problem has to do with how the {$old} path is calculated.

I printed out the $replacement value from line 299: $item['value'] = preg_replace("/$regex/e", $replacement, $item['value']);

When using [current-user:name]/example as the file path:
$replacement = _filefield_paths_replace_path_uri_scheme('\1', 'public://sunflowersnew.jpg', 'public://username/example/sunflowersnew.jpg') . '\2username/example/sunflowersnew.jpg'
(Note - all of these file names refer to the new file name, none of them reference the old one, and the "old" path doesn't include the token-defined path.)

When using my custom token [current-group:url:path] in the file path:
$replacement = _filefield_paths_replace_path_uri_scheme('\1', 'public://[current-group:url:path]/example/sunflowersnew.jpg', 'public://gibson/example/sunflowersnew.jpg') . '\2gibson/example/sunflowersnew.jpg'
Note - it leaves the token in the "old" value. The value of the token in this example is "gibson"

funex’s picture

Hi jastraat,

I'm finding this error also. I'm using tokens to upload images to relevant folders.

Did you find a solution to this?

jastraat’s picture

Since _filefield_paths_replace_path is only present to update links to files within textareas (something somewhat unrelated to the main purpose of this module), I just commented out calls to that function.

Roulion’s picture

Priority: Major » Critical

This is a quite critical bug. Is it possible to have a dev version which fix it ?

Thank a lot

Deciphered’s picture

Roulion,

I haven't had time to attempt to reproduce the issue, but patches are always welcome. I should have the time very soon as I am at Drupalcon which gives me additional dev time, but I can't guarantee that.

Roulion’s picture

OK thank for your answer..
basically, i thought jastraat had a tmporary patch (comment the function..).

Please do as you can.

Roulion’s picture

With the last dev release, it works when the file path has only one token.
But when i use with several (like /node/[node:field-one]-[node:field-two]), i reproduce the bug.

Strangely, when i use somethng like /node/[node:field-one]/[node:field-two], i don't have the preg_replace error.

Maybe it can help

Roulion’s picture

I can confirm my analysis. i changed my fielfield path to something like /node/[node:field-one]/[node:field-two] and it worked correctly.

to reproduced, you have to set a path like arg(0)/(arg(1)/arg(2) where arg(x) looks like
[token:one]-[token:two].

nevertheless, it seeams the multivalue file field causes problems since only the first file is handled.

Deciphered’s picture

Status: Active » Postponed (maintainer needs more info)

Hi Roulion,

I tried what I think you meant but I was still unable to reproduce this issue. Can you try to give me an exact step-by-step guide (install modules, configure fields like so, create node, etc) that guarantees the issue on your site, including specifics on exactly what is happening and what you expect to happen, because I'm just not seeing any issues whatsoever.

Cheers,
Deciphered.

Roulion’s picture

Actually, i only encounter this issue with one node type. I migrated from D6 to D7.12.

In the node type i have 3 image fields

- field 1 : only one value; path = node/joueurs/[node:title] - translitteration enabled, pathauto disabled
- field 2 : only one value; path = node/joueurs/[node:title] - translitteration enabled, pathauto disabled
- field 3 : multivalue ; path = node/joueurs/[node:title]/galerie - translitteration enabled, pathauto disabled

When i create node : the file path is ok but all text-field are wiped out.
When i edit node, if i add/edit images, the file path is ok but all text-field are wipe out.

in dblog, i have
Warning: preg_replace() [function.preg-replace]: Compilation failed: range out of order in character class at offset 224 in _filefield_paths_replace_path() (line 299 of /public_html/sites/pages.wustl.edu/modules/filefield_paths/filefield_paths.module).

With the latest-dev release, as i said, when i used the retro-active option, only one image of the galerie field was treated by batch. When i add several image, only the first use the fiel field path settings, others uses the defalt directory file settings (joueur/[current-page:url:args:1] in my case). I suppose there might be a problem with it. I will create a separate ticket for this. For my other node type, where i don't use multivalue field for images, i can't reproduce the bug..

I hope it may help you

Roulion’s picture

If i enable pathauto settings cleand + translitteration, it doesn't change anything (same issue)

Roulion’s picture

rond49’s picture

I removed my previous comment, as I started a more organized search for the bug.

I have installed a fresh 7.12, added the modules FFPs, Views, Token, Ctools (Chaos Tools only) and Pathauto.
Tried many things, and couldn't recreate the bug.

The following modules are enabled in a site where I encounter the bug - one of the two tokens I use goes blank in the generated path:
Administration menu, Taxonomy Manager, Webform, Views Autocomplete Filters, Views Data Export, Services, Unique Field,
Libraries, Custom Search, Date (several), Feeds (several), References, Link, OpenLayers (several), and - Image URL Formatter.

I suspect the last one, Image URL Formatter, might have something to do with the strange behavior I see.
Not sure this helps; just my 2 cents..

Roulion’s picture

With a fresh install, it works fine.

the point should come from my porting D6->D7. That's quite hard to debug.
I hope the multivalue fix should correct the point

jbubik’s picture

Status: Postponed (maintainer needs more info) » Active
FileSize
2.18 KB

Greetings! I think I've traced the bug down to the root cause: PREG expression containing unescaped []-brackets with a range not being in alphabetical order. Applies only to sites previously setting default image path to something like "[current-page:url:args:1]". The executed command is:

preg_replace("/(https:\/\/localhost\/system\/files\/geogallery\/%5Bcurrent-page%3Aurl%3Aargs%3A1%5D\/pic_2011-02-18_1921.jpg|\/system\/files\/geogallery\/%5Bcurrent-page%3Aurl%3Aargs%3A1%5D\/pic_2011-02-18_1921.jpg|private:\/\/)(styles\/.*?\/private\/|)(geogallery\/[current-page:url:args:1]\/pic_2011-02-18_1921.jpg)/e", "_filefield_paths_replace_path_uri_scheme('\1', 'private://geogallery/[current-page:url:args:1]/pic_2011-02-18_1921.jpg', 'private://geogallery/pic_2011-02-18_1921.jpg') . '\2geogallery/pic_2011-02-18_1921.jpg'", "my_body_text");

The expression "[current-page:url:args:1]" comes from configuration of "image"-field. The value is used unescaped in a regular expression. Regular expression "[t-p]" is invalid and causes preg_replace to return NULL value. Expression [a-z] is OK, expression [z-a] is invalid.

The real root-cause is in configuration of image-field. Without File (Field) Paths module enabled, you can configure default file directory. Many people use something like [current-page:url:args:1] there. In reality, that does not work, it takes the string "[current-page:url:args:1]" as a name of directory under "files". Once you install File (Field) Paths module the settings for image-field changes. You can see the original settings no more, but it is still there! To recreate the bug disable File (Field) Paths module. Edit your image-field's settings and fill the default directory with value like [current-page:url:args:1]. Now enable File (Field) Paths module. BANG! You are in trouble now! You can use the same approach as a workaround on existing installations of D7. Disable File (Field) Paths module, edit image-field, set default directory to empty string, enable File (Field) Paths module.

My suggestion is to apply this patch to (at least) prevent preg_replace-errors from wiping out Text-fields contents:

*** filefield_paths.module.orig 2012-05-23 15:52:41.000000000 +0200
--- filefield_paths.module      2012-05-23 16:11:33.000000000 +0200
***************
*** 281,287 ****
  function _filefield_paths_replace_path($old, $new, $entity) {
    // Build regular expression.
    $info = parse_url(file_stream_wrapper_uri_normalize($old));
!   $info['path'] = !empty($info['path']) ? $info['path'] : '';
    $absolute = str_replace("{$info['host']}{$info['path']}", '', file_create_url($old));
    $relative = parse_url($absolute, PHP_URL_PATH);
    $regex = str_replace('/', '\/', "({$absolute}|{$relative}|{$info['scheme']}://)(styles/.*?/{$info['scheme']}/|)({$info['host']}{$info['path']})");
--- 281,287 ----
  function _filefield_paths_replace_path($old, $new, $entity) {
    // Build regular expression.
    $info = parse_url(file_stream_wrapper_uri_normalize($old));
!   $info['path'] = !empty($info['path']) ? str_replace('[', '\[', str_replace(']', '\]', $info['path'] ) ) : '';
    $absolute = str_replace("{$info['host']}{$info['path']}", '', file_create_url($old));
    $relative = parse_url($absolute, PHP_URL_PATH);
    $regex = str_replace('/', '\/', "({$absolute}|{$relative}|{$info['scheme']}://)(styles/.*?/{$info['scheme']}/|)({$info['host']}{$info['path']})");
***************
*** 296,302 ****
      if ($field['module'] == 'text' && isset($entity->{$field['field_name']}) && is_array($entity->{$field['field_name']})) {
        foreach ($entity->{$field['field_name']} as &$language) {
          foreach ($language as &$item) {
!           $item['value'] = preg_replace("/$regex/e", $replacement, $item['value']);
          }
        }
      }
--- 296,307 ----
      if ($field['module'] == 'text' && isset($entity->{$field['field_name']}) && is_array($entity->{$field['field_name']})) {
        foreach ($entity->{$field['field_name']} as &$language) {
          foreach ($language as &$item) {
!           $newval = preg_replace("/$regex/e", $replacement, $item['value']);
!           if($newval!==NULL){
!             $item['value'] = $newval;
!           }else{
!             trigger_error ("Error in preg_replace(\"/$regex/e\", $replacement, $item[value])",E_USER_WARNING);
!           };
          }
        }
      }

Please note line 283 in 7.x-1.x-dev:
$info = parse_url(file_stream_wrapper_uri_normalize($old));
That returns an array with a string "[current-page:url:args:1]" in it (or any other default directory for images configured in your D7). Escaping the []-brackets should make preg_replace happy. That is the first part of the patch. Honestly I do not know whether it will correct references to images in text-fields, but will drop special meaning to [] in regular expression.
The second part of the patch is more generic. It verifies the return value of preg_replace. If the return value is NULL it emits a warning. That protects the data should anything go wrong anytime in future.

Hope that helps!

Roulion’s picture

The patch seems to work. I no longer have the pb

thanks a lot

masipila’s picture

Status: Active » Reviewed & tested by the community

I have a dev-site that I just upgraded from D6 to D7. I can verify that the bug is triggered on my site when using the beta3 and latest dev-version of this module (2012-Mar-26) when removing and uploading an image during the same edit.

I can also verify that patching the latest dev with the patch in #20 resolves the issue. Thanks jbubik for investigating and providing the patch!

Cheers,
Markus

andypost’s picture

Status: Reviewed & tested by the community » Needs work

Please provide a patch in unified format see instructions

Also patch should be against 7.x-1.x dev

Deciphered’s picture

--- 296,307 ----
!           $newval = preg_replace("/$regex/e", $replacement, $item['value']);
!           if($newval!==NULL){
!             $item['value'] = $newval;
!           }else{
!             trigger_error ("Error in preg_replace(\"/$regex/e\", $replacement, $item[value])",E_USER_WARNING);

Not mentioning the Patch format, this code does not meet the Drupal coding standards.

mjonesdinero’s picture

Assigned: Unassigned » mjonesdinero
Status: Needs work » Needs review
FileSize
1.52 KB

Hi Stuart

i hope this watch will be okie for this issue
just give me feedback if anything is wrong..thanks

Deciphered’s picture

Status: Needs review » Needs work
+++ b/filefield_paths.moduleundefined
@@ -296,7 +296,12 @@ function _filefield_paths_replace_path($old, $new, $entity) {
+          $newval = preg_replace("/$regex/e", $replacement, $item['value']);
+          if($newval!==NULL){
+            $item['value'] = $newval;
+          }else{
+            trigger_error ("Error in preg_replace(\"/$regex/e\", $replacement, $item[value])",E_USER_WARNING);

This doesn't meet Drupal coding standards (http://drupal.org/coding-standards/), nor should trigger_error() be used, instead it should use drupal_set_message() and/or watchdog().

mjonesdinero’s picture

Status: Needs work » Needs review
FileSize
1.54 KB

here is another patch hope it is ok now plus the standards

Deciphered’s picture

Status: Needs review » Needs work
+++ b/filefield_paths.moduleundefined
@@ -296,7 +296,12 @@ function _filefield_paths_replace_path($old, $new, $entity) {
+          if ($newval != NULL) {

Use !is_null() instead of != NULL

+++ b/filefield_paths.moduleundefined
@@ -296,7 +296,12 @@ function _filefield_paths_replace_path($old, $new, $entity) {
+          } else {

As per http://drupal.org/coding-standards/, this should be:

}
else {
+++ b/filefield_paths.moduleundefined
@@ -296,7 +296,12 @@ function _filefield_paths_replace_path($old, $new, $entity) {
+		    watchdog('Error in preg_replace(\"/$regex/e\", $replacement, $item[value])', $item['value']->getMessage(), WATCHDOG_ERROR);

Indentation is wrong here, should use spaces instead of tabs.

Deciphered’s picture

Also, the watchdog arguments are incorrect.

mjonesdinero’s picture

here it is... more documentations on proper standard will make me better

mjonesdinero’s picture

Status: Needs work » Needs review
FileSize
1.57 KB

how about this

mjonesdinero’s picture

the last update i have made from the feedbacks i have recieved from Stuart Through email

jastraat’s picture

When using multiple tokens within a file path for a file or image field, the latest dev still wipes the content from all textareas after removing and replacing a file in the same node.

This patch does prevent the textareas from being wiped, but I am still getting the following error:

Warning: preg_replace() [function.preg-replace]: Compilation failed: range out of order in character class at offset 246 in _filefield_paths_replace_path() (line 300 of /modules/filefield_paths/filefield_paths.module).

The $regex used in the function contains the url encoded token, not the token value.
Example: %5Bcurrent-group%3Aurl%3Apath%5D for [current-group:url:path]

I believe this causes the error.

jbubik’s picture

Hi jastraat! Current dev version (7.x-1.x-dev dated 2012-Aug-10) does NOT include any of the proposed patches. Are you sure you have applied the patch from #32 manually? If you did, you should have received some kind of error in your log. Can you post it here in a complete form? I'd like to help you, but I need to see the value of $regex. That "offset 246" refers to 246th character in $regex variable. And the value of $regex is logged to drupal logs via the function watchdog.
BTW you can "debug" your problem yourself by adding this to the module's code at line 300 before preg_replace:

echo "REGEX: ".htmlspecialchars($regex)."<br>\n"; //this shows the value to browser

Post here the REGEX value just prior to the warning message from preg_replace.
Hope that helps you. I am not a drupal nor module developer. Being completely new to drupal, I don't know the coding standards :-(

jastraat’s picture

I did apply the patch, and I did do a big of debugging as to the value of the $regex. In my comment, I mentioned that the token is still in the regex - not the value of the token - which is I believe what is causing the problem.

To be even more explicit:
Error in preg_replace(\"/(http:\/\/test.pages.wustl.edu\/files\/pages\/%5Bcurrent-group%3Aurl%3Apath%5D\/site\/slideshow\/keshavarz.jpg|\/files\/pages\/%5Bcurrent-group%3Aurl%3Apath%5D\/site\/slideshow\/keshavarz.jpg|public:\/\/)(styles\/.*?\/public\/|)([current-group:url:path]\/site\/slideshow\/keshavarz.jpg)/e\", "_filefield_paths_replace_path_uri_scheme('\1', 'public://[current-group:url:path]/site/slideshow/keshavarz.jpg', 'public://awf/site/slideshow/keshavarz.jpg') . '\2awf/site/slideshow/keshavarz.jpg'", fostering community :: defending diversity :: advancing the interests of women faculty)

Stolzenhain’s picture

Just to mention I had the same problem (Drupal6>7, Filefield Path emptying text fields), without any configured path tokens at all.

Deciphered’s picture

Status: Needs review » Closed (cannot reproduce)

I've never been able to reproduce this issue, and given that this issue is in a completely unruly state I am thinking that the best approach is to recommend that everyone try the latest dev release and if you still experience this issue open a new issue.

I am closing this issue as cannot reproduce.

Roulion’s picture

I tested it yesterday and it seems OK

jastraat’s picture

FileSize
15.91 KB

I just confirmed that this bug is still active in the 7.x-1.0-beta4 of this module.
I was able to recreate it by using

[current-page:url:path]/sites

as the file path. See attached screenshot for settings.

Then I edited an existing node with an image field and a body field, removed the attached image, uploaded a new one, and saved the node.

The body field was erased.

jastraat’s picture

Version: 7.x-1.0-beta3 » 7.x-1.x-dev
Status: Closed (cannot reproduce) » Active

Actual error message:
Warning: preg_replace() [function.preg-replace]: Compilation failed: range out of order in character class at offset 235 in _filefield_paths_replace_path() (line 330 of /modules/filefield_paths/filefield_paths.module).

jastraat’s picture

$instance = the instance of a file field in a given content type.

In filefield_paths_filefield_paths_process_file(), there's a check to see if $file !== $old_file. This will always evaluate to true because:
$file['uri'] = public/private . $instance['settings']['filefield_paths']['file_path']['value']
while
$old_file['uri'] = public/private . $instance['settings']['file_directory']

Note: the old file uri is using the UNUSED file directory variable. If the file directory variable (which is no longer directly editable once filefield paths is enabled), contains a token, this error is generated.

I think in earlier versions of this module, filefield paths may have set the file directory as well as the filefield_paths file path value. The fix was to set the file directory setting for the field instance to empty.

It's not an issue with fresh installs with this module. However - the comparison in filefield_paths_filefield_paths_process_file() should probably be modified.

jastraat’s picture

Title: All text-based fields wiped empty after replacing a file in a node and saving. » filefield_paths_filefield_paths_process_file() uses file_directory setting instead of filefield paths file path for comparison.
Priority: Critical » Minor
Deciphered’s picture

Title: filefield_paths_filefield_paths_process_file() uses file_directory setting instead of filefield paths file path for comparison. » All text-based fields wiped empty after replacing a file in a node and saving.
Version: 7.x-1.x-dev » 7.x-1.0-beta4
Priority: Minor » Normal

@jastraat,

You've gone and alleged that the original issue is confirmed, then you've gone and changed the whole issue to a completely unrelated issue.... please don't do that. If I where to come back to this issue after a long break, based on the title and the last comment I would no longer have any idea about what 90% of people are complaining about and would skip over it and close this issue without ever resolving the original issue.

In cases that you find a second issue, report it as a second issue please.

Changing the title back to it's original state.

jastraat’s picture

@Deciphered - The first issue is caused by the 2nd issue.

Deciphered’s picture

Sure, possibly not clear enough in the comment, but I'll take that into account when I get some time this afternoon to look into the issue.

Deciphered’s picture

Status: Active » Closed (cannot reproduce)

@jastraat,

Had a look into the issue, and you are incorrect, $old_file is copied from $file at line 57, and in the case that the tokens don't cause the actual $file['filename] and $file['uri'] to be generated differently, then $old_file will still equal $file at line #68.

I'm going to have to mark this issue as closed (cannot reproduce) at this point, as I've never been able to reproduce the issue and have never been given enough information to track it down.

If anyone is still experiencing this issue with the latest version of File (Field) Paths then feel free to reopen as long as you are willing to help get to the bottom of this issue.