{"record":{"id":"8b9c89ffcc23a622","repo":"tursodatabase/turso","slug":"invalid-page-size-stored","errorCode":null,"errorMessage":"invalid page size stored","messagePattern":"invalid page size stored","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"core/storage/pager.rs","lineNumber":3103,"sourceCode":"        self.dirty_pages.write().clear();\n        Ok(())\n    }\n\n    /// Get the current page size. Returns None if not set yet.\n    pub fn get_page_size(&self) -> Option<PageSize> {\n        let value = self.page_size.load(Ordering::SeqCst);\n        if value == 0 {\n            None\n        } else {\n            PageSize::new(value)\n        }\n    }\n\n    /// Get the current page size, panicking if not set.\n    pub fn get_page_size_unchecked(&self) -> PageSize {\n        let value = self.page_size.load(Ordering::SeqCst);\n        turso_assert_ne!(value, 0);\n        PageSize::new(value).expect(\"invalid page size stored\")\n    }\n\n    pub(crate) fn has_wal(&self) -> bool {\n        self.wal.is_some()\n    }\n\n    #[cfg(test)]\n    pub(crate) fn wal_shared_ptr(&self) -> Option<usize> {\n        self.wal\n            .as_ref()\n            .and_then(|wal| wal.as_any().downcast_ref::<crate::storage::wal::WalFile>())\n            .map(crate::storage::wal::WalFile::shared_ptr)\n    }\n\n    /// Set the page size. Used internally when page size is determined.\n    pub fn set_page_size(&self, size: PageSize) {\n        self.page_size.store(size.get(), Ordering::SeqCst);\n    }","sourceCodeStart":3085,"sourceCodeEnd":3121,"githubUrl":"https://github.com/tursodatabase/turso/blob/492c4a71cd7c2649e7df83da1471b74f4b1c7aa9/core/storage/pager.rs#L3085-L3121","documentation":"Pager::get_page_size_unchecked() reads the atomic page_size, asserts it is non-zero (turso_assert_ne!), then validates it with PageSize::new(value).expect(\"invalid page size stored\"). PageSize::new only accepts powers of two in [512, 65536]; a non-zero value outside that set (e.g. 3000 or 131072) panics.","triggerScenarios":"A bogus page size was stored into the pager - a corrupted or unvalidated database header value read at open time, or embedder code writing an arbitrary usize into pager.page_size instead of a PageSize-validated value.","commonSituations":"Opening corrupted or hand-crafted/fuzzed database files, page-size plumbing regressions between engine versions, programmatic page-size changes without validation.","solutions":["Prefer the checked variant get_page_size() (returns Option) and handle None instead of get_page_size_unchecked()","Validate the header at open (PRAGMA page_size, integrity check) when loading untrusted files","If setting the size programmatically, construct PageSize::new(v) first and store the validated value"],"exampleFix":"// before\nlet page_size = pager.get_page_size_unchecked(); // panics on invalid stored value\n\n// after\nlet Some(page_size) = pager.get_page_size() else {\n    return Err(LimboError::Corrupt(\"page size not set or invalid\".into()));\n};","handlingStrategy":"validation","validationCode":"// Prefer the checked accessor and handle the unset/invalid case:\nmatch pager.get_page_size() {\n    Some(ps) => { /* proceed with ps */ }\n    None => return Err(LimboError::Corrupt(\"page size not set or invalid\".into())),\n}\n// When opening untrusted files, validate up front:\nlet ps = conn.query_row(\"PRAGMA page_size\", [], |r| r.get::<_, i64>(0))?;","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Avoid get_page_size_unchecked() in embedder code; use the Option-returning get_page_size()","Validate PRAGMA page_size / run integrity checks before operating on untrusted database files","Only store PageSize-validated values when configuring sizes programmatically"],"tags":["pager","page-size","header","validation","panic"],"backgroundTag":"invalid-page-size","analyzedSha":"492c4a71cd7c2649e7df83da1471b74f4b1c7aa9","analyzedAt":"2026-08-20T07:02:18.389Z","contentChangedAt":"2026-08-20T07:02:18.389Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}