Commit 4bdd029d authored by jan.koester's avatar jan.koester
Browse files

test

parent 4cf45513
Loading
Loading
Loading
Loading
+39 −4
Changes for editor/src/htmlimport.cpp: 39 added lines, 4 removed lines.
Original line number Diff line number Diff line
@@ -1571,10 +1571,32 @@ bool blogi::htmlimport::convertHtmlToWidgetXml(const std::string &html,
    // globalJs (inline <script> blocks, with no src, are left untouched).
    const int kMaxExternalStylesheets = 10;
    const size_t kMaxStylesheetBytes = 3 * 1024 * 1024;
    // Cumulative cap across ALL fetched stylesheets combined, independent of
    // the per-sheet/count caps above: a real page-builder site can easily
    // have 10 stylesheets a few hundred KB each, and the resulting page-level
    // CSS is still something a browser renders fine. Kept far more generous
    // than the JS budget below since CSS failing to apply is silently
    // degraded styling, not a broken/oversized response.
    const size_t kMaxTotalCssBytes = 2 * 1024 * 1024;
    int externalCssSeen = 0;
    size_t totalCssBytes = 0;

    const int kMaxExternalScripts = 10;
    const size_t kMaxScriptBytes = 5 * 1024 * 1024;
    // Cumulative cap across ALL fetched scripts combined: unlike CSS, a
    // fetched external script's contents get inlined into the final page's
    // GlobalJs verbatim and executed as-is (see webedit_api.cpp's
    // handleImportHtml/renderTree) -- but it was written for the ORIGINAL
    // page's DOM, not blogi's widget-rendered version of it, so it's already
    // unlikely to do anything useful, and a large bundle (a full framework
    // runtime, analytics, etc.) only adds risk (uncaught errors breaking the
    // rest of the inlined script) and response size for no real benefit.
    // Confirmed against a real site: 9 external scripts (including a full
    // React build) totalling 2.7MB inlined this way correlated with preview/
    // publish requests failing outright, likely from the resulting multi-MB
    // response tripping something size-related downstream -- so this is
    // capped much tighter than the per-script/stylesheet budgets above.
    const size_t kMaxTotalJsBytes = 300 * 1024;
    int externalJsSeen = 0;
    std::string globalJs;

@@ -1592,7 +1614,7 @@ bool blogi::htmlimport::convertHtmlToWidgetXml(const std::string &html,
                                   src.compare(0, 8, "https://") == 0;

                if (isAbsolute) {
                    if (externalJsSeen >= kMaxExternalScripts) {
                    if (externalJsSeen >= kMaxExternalScripts || globalJs.size() >= kMaxTotalJsBytes) {
                        if (outStats) outStats->jsFailed++;
                    } else {
                        externalJsSeen++;
@@ -1602,7 +1624,15 @@ bool blogi::htmlimport::convertHtmlToWidgetXml(const std::string &html,
                        try {
                            std::vector<std::uint8_t> bytes;
                            std::string fetchError;
                            if (fetchExternalResource(src, kMaxScriptBytes, "",
                            // Cap THIS fetch to whatever's left of the total
                            // JS budget, not just the flat per-script cap --
                            // otherwise a single large script fetched while
                            // still under budget (e.g. the first one) could
                            // blow straight past kMaxTotalJsBytes in one go,
                            // and only later scripts would actually get
                            // rejected by the size check above.
                            size_t remainingBudget = kMaxTotalJsBytes - globalJs.size();
                            if (fetchExternalResource(src, std::min(kMaxScriptBytes, remainingBudget), "",
                                                       bytes, fetchError)) {
                                if (!globalJs.empty()) globalJs += "\n;\n";
                                globalJs.append(bytes.begin(), bytes.end());
@@ -1657,7 +1687,7 @@ bool blogi::htmlimport::convertHtmlToWidgetXml(const std::string &html,
                                       href.compare(0, 8, "https://") == 0;

                    if (rel.find("stylesheet") != std::string::npos && isAbsolute) {
                        if (externalCssSeen >= kMaxExternalStylesheets) {
                        if (externalCssSeen >= kMaxExternalStylesheets || totalCssBytes >= kMaxTotalCssBytes) {
                            if (outStats) outStats->cssFailed++;
                        } else {
                            externalCssSeen++;
@@ -1669,8 +1699,13 @@ bool blogi::htmlimport::convertHtmlToWidgetXml(const std::string &html,
                            try {
                                std::vector<std::uint8_t> bytes;
                                std::string fetchError;
                                if (fetchExternalResource(href, kMaxStylesheetBytes,
                                // See the analogous JS budget comment above:
                                // cap this fetch to what's left of the total
                                // CSS budget, not just the flat per-sheet cap.
                                size_t remainingBudget = kMaxTotalCssBytes - totalCssBytes;
                                if (fetchExternalResource(href, std::min(kMaxStylesheetBytes, remainingBudget),
                                                           "text/css", bytes, fetchError)) {
                                    totalCssBytes += bytes.size();
                                    std::string cssText(bytes.begin(), bytes.end());
                                    // This sheet's own url(...) references are
                                    // relative to ITS location (href), not the