Repository: openemr/openemr (language: php)

Issue:
bug: setup.php incorrectly compares and flags memory_limit
### Describe the bug

memory_limit in php config is in bytes, but setup.php compares the value to the integer `256`, expecting megabytes. It also doesn't account for [shorthand](https://www.php.net/manual/en/faq.using.php#faq.using.shorthandbytes).

(Also, Documentation/INSTALL calls for 512M, so 256 is inconsistent with that.)

### To Reproduce

Steps to reproduce the behavior:
1. Configure php.ini so that `memory_limit = 512M`
2. Launch a new installation of openemr with that configuration and notice that setup.php flags the memory_limit as unsafe.
3. Try again, configure php.ini so that `memory_limit = 134217728` (that is, 128M, in bytes)
4. Launch a new installation of openemr with that configuration and notice that setup.php does _not_ flag the memory_limit, even though it is less than 256M.

### Expected behavior

setup.php should flag values under 512M and not flag values >=512M.

### Client configuration

- Browser: Firefox 137.0.2
- OpenEMR version: `master` branch.
- Operating system: macOS 15.4.1


Discussion / hints:

Fix patch:
diff --git a/setup.php b/setup.php
index 6f246ce126d..0e5487be637 100644
--- a/setup.php
+++ b/setup.php
@@ -1492,7 +1492,26 @@ function cloneClicked() {
                     $post_max_size = ini_get('post_max_size');
                     $post_max_size_style = $post_max_size < 30 ? 'text-danger' : '';
                     $memory_limit = ini_get('memory_limit');
-                    $memory_limit_style = $memory_limit < 256 ? 'text-danger' : '';
+                    // Convert from shorthand to M
+                    if (preg_match('/^(\d+)([KMG]?)$/', $memory_limit, $matches)) {
+                        switch ($matches[2]) {
+                            case 'K':
+                                $memory_limit_mb = intdiv($matches[1], 1024);
+                                break;
+                            case 'M':
+                                $memory_limit_mb = (int)$matches[1];
+                                break;
+                            case 'G':
+                                $memory_limit_mb = $matches[1] * 1024;
+                                break;
+                            case '':
+                                $memory_limit_mb = intdiv($matches[1], 1024 * 1024);
+                                break;
+                        }
+                    } else {
+                        $memory_limit_mb = intdiv($memory_limit, 1024 * 1024);
+                    }
+                    $memory_limit_style = $memory_limit_mb < 512 ? 'text-danger' : '';
                     $mysqli_allow_local_infile = ini_get('mysqli.allow_local_infile') ? 'On' : 'Off';
                     $mysqli_allow_local_infile_style = (strcmp($mysqli_allow_local_infile, 'On')  === 0) ? '' : 'text-danger';
 
@@ -1540,7 +1559,7 @@ function cloneClicked() {
                                 </tr>
                                 <tr>
                                     <td>memory_limit</td>
-                                    <td>at least 256M</td>
+                                    <td>at least 512M</td>
                                     <td class='" . attr($memory_limit_style) . "'>" . text($memory_limit) . "</td>
                                 </tr>
                                 <tr>
@@ -1793,7 +1812,8 @@ function cloneClicked() {
                                         <button type='submit' value='Continue'><b>Proceed to Step 1</b></button>
                                     </form>
 FRM;
-                        echo $form . "\r\n";                        }
+                        echo $form . "\r\n";
+                    }
             }
                         $bot = <<<BOT
                                     </div>


Test patch: