Skip to content
This repository was archived by the owner on Apr 29, 2026. It is now read-only.

⏺ Done! Here's what was accomplished:#81

Merged
navicore merged 3 commits intomainfrom
shopping-cart
Dec 13, 2025
Merged

⏺ Done! Here's what was accomplished:#81
navicore merged 3 commits intomainfrom
shopping-cart

Conversation

@navicore
Copy link
Copy Markdown
Owner

Summary

  1. Updated ROADMAP.md
  • Changed ffi:readline references to ffi:libedit
  • Updated Use Cases section
  • Updated Tab Completion section noting callback dependency (shelved)
  1. Extended sqlite.toml with Prepared Statements

Added 8 new FFI functions:

  • db-prepare - Compile SQL to statement
  • db-step - Execute/fetch rows
  • db-finalize - Clean up statement
  • db-reset - Reset for re-execution
  • db-column-int - Get integer column
  • db-column-text - Get text column
  • db-column-count - Get column count
  • db-bind-int, db-bind-text - Parameter binding
  1. Created Shopping Cart Example (examples/shopping-cart/)

A complete REST server demonstrating:

  • HTTP API: GET/POST endpoints with query parameter parsing
  • SQLite Persistence: Products, cart items, orders tables
  • Prepared Statements: Queries with result iteration
  • Transactions: Checkout uses BEGIN/COMMIT/ROLLBACK
  • Concurrent Handling: Strands for parallel requests

Files created:

  • shopping-cart.seq - Main server (~670 lines)
  • sqlite.toml - FFI manifest (copied for convenience)
  • README.md - Documentation

Test Results

Products: 1. Apple - $100 (stock: 50)
Cart: #1: Apple x 2 @ $100 = $200
Checkout: Order total: $550 (3 items)
Stock: Apple 50→48, Milk 20→19

  Summary

  1. Updated ROADMAP.md

  - Changed ffi:readline references to ffi:libedit
  - Updated Use Cases section
  - Updated Tab Completion section noting callback dependency (shelved)

  2. Extended sqlite.toml with Prepared Statements

  Added 8 new FFI functions:
  - db-prepare - Compile SQL to statement
  - db-step - Execute/fetch rows
  - db-finalize - Clean up statement
  - db-reset - Reset for re-execution
  - db-column-int - Get integer column
  - db-column-text - Get text column
  - db-column-count - Get column count
  - db-bind-int, db-bind-text - Parameter binding

  3. Created Shopping Cart Example (examples/shopping-cart/)

  A complete REST server demonstrating:
  - HTTP API: GET/POST endpoints with query parameter parsing
  - SQLite Persistence: Products, cart items, orders tables
  - Prepared Statements: Queries with result iteration
  - Transactions: Checkout uses BEGIN/COMMIT/ROLLBACK
  - Concurrent Handling: Strands for parallel requests

  Files created:
  - shopping-cart.seq - Main server (~670 lines)
  - sqlite.toml - FFI manifest (copied for convenience)
  - README.md - Documentation

  Test Results

  Products: 1. Apple - $100 (stock: 50)
  Cart:     #1: Apple x 2 @ $100 = $200
  Checkout: Order total: $550 (3 items)
  Stock:    Apple 50→48, Milk 20→19
@claude
Copy link
Copy Markdown

claude Bot commented Dec 13, 2025

Pull Request Review - Shopping Cart Example

Summary

This PR adds a comprehensive shopping cart REST server example demonstrating SQLite prepared statements, HTTP routing, database transactions, and concurrent request handling. The implementation is well-documented and showcases advanced FFI usage.

Strengths

Code Quality

  • Excellent documentation with clear comments explaining each section
  • Consistent style following concatenative programming idioms
  • Proper stack effect declarations for all words
  • Well-organized logical separation into sections

FFI Implementation

  • Complete prepared statement API with 8 new functions
  • Good documentation in manifest with clear usage patterns
  • Correct memory management using by_ref for out parameters

Architecture

  • Proper transaction handling with BEGIN/COMMIT/ROLLBACK
  • Concurrent design with per-request DB connections
  • Error handling with return code checks

Critical Security Concerns

SQL Injection Vulnerability

Location: shopping-cart.seq:343-358, 360-369

The add-to-cart and remove-from-cart functions use string concatenation to build SQL queries with user input directly from query parameters, creating SQL injection vulnerabilities.

Attack vector:
curl -X POST "http://localhost:8080/cart/add?product=1);DROP TABLE products;--&qty=1"

Impact: Arbitrary SQL execution, data deletion, modification, or exfiltration

Recommendation: Use prepared statements with db-bind-int for parameters, or add strict input validation to ensure parameters are valid integers before concatenation.

Missing Input Validation

Location: shopping-cart.seq:498-522

  • No validation that product and qty parameters are valid integers
  • No bounds checking for negative quantities or overflow
  • No verification that product_id exists
  • No stock availability check before adding items

Race Condition in Stock Updates

Location: shopping-cart.seq:400-406

The stock update query could set stock to negative values if there is insufficient inventory. Transaction should verify stock availability.

Code Issues

  • Potential resource leaks if errors occur during request processing (shopping-cart.seq:613-628)
  • Missing error code checks in seed-products function (shopping-cart.seq:176-189)
  • Inefficient use of prepared statements for single-execution queries (shopping-cart.seq:375-398)

Documentation Issues

  • Build command inconsistency: seq file references examples/ffi/sqlite/sqlite.toml but manifest is at examples/shopping-cart/sqlite.toml
  • Missing documentation of error scenarios, concurrent behavior, and stock constraints

Test Coverage

Missing automated tests, SQL injection test cases, concurrency tests, and error path testing.

Suggestions for Improvement

High Priority

  1. Fix SQL injection vulnerabilities
  2. Add input validation
  3. Fix stock update query to prevent negative stock
  4. Update build command in code comments

Medium Priority

  1. Add automated tests
  2. Document error scenarios
  3. Add stock availability checks
  4. Improve error handling and resource cleanup

Conclusion

This is an excellent addition demonstrating real-world FFI usage, database transactions, HTTP routing, and concurrency. However, the SQL injection vulnerabilities are critical and should be addressed before merge to avoid teaching unsafe practices.

Overall Assessment: 7/10

  • Code quality: 8/10
  • Documentation: 8/10
  • Security: 3/10 (critical issues)
  • Test coverage: 2/10
  • Architecture: 9/10

  1. SQL injection vulnerabilities - Rewrote add-to-cart and remove-from-cart using prepared statements with db-bind-int instead of string concatenation
  2. Input validation - Added string->int parsing with success checking in handlers, plus validation that quantity must be positive
  3. Stock race condition - Added check-stock-available function that verifies sufficient stock before checkout, and updated update-stock query to include WHERE stock >= ? to prevent negative values
  4. Build command path - Fixed header comment from examples/ffi/sqlite/sqlite.toml to examples/shopping-cart/sqlite.toml

  The shopping cart example now demonstrates secure SQLite usage with parameterized queries.
@claude
Copy link
Copy Markdown

claude Bot commented Dec 13, 2025

PR Review: Shopping Cart REST Server Example

Great work on this comprehensive example! The shopping cart demo effectively showcases multiple Seq features working together. I've reviewed the code for quality, security, and best practices.

Strengths

Code Quality

  • Excellent documentation: Clear comments, well-structured README with build/test instructions
  • Good separation of concerns: Clean division into HTTP, database, and business logic sections
  • Consistent naming: Stack effect comments match the Seq concatenative style
  • Resource cleanup: Proper db-finalize calls after prepared statements
  • Error handling: Appropriate checks for database operations and user input

Security (Well Addressed in Commit 2)

  • SQL injection prevention: Properly uses prepared statements with db-bind-int for all user input (lines 346-385, 390-401)
  • Input validation: Validates quantity is positive (line 583), checks parameter presence, validates numeric parsing
  • Stock validation: check-stock-available prevents negative stock (lines 432-450)
  • Race condition mitigation: Stock check uses constraint in UPDATE query (line 458)

FFI Design

  • Well-documented API: The sqlite.toml prepared statement section (lines 81-212) is exemplary
  • Proper ownership: Uses ownership = static for SQLite-managed strings
  • Good use of fixed values: -1 for SQLITE_TRANSIENT is correctly specified

Architecture

  • Transaction safety: Checkout properly uses BEGIN/COMMIT/ROLLBACK pattern
  • Concurrent handling: Each connection gets its own DB connection (line 673), avoiding shared state issues
  • Good HTTP helpers: Clean abstraction for HTTP responses and request parsing

Areas for Consideration

1. SQL Injection in create-order (Line 462-473)

Severity: MEDIUM

The create-order function uses string concatenation instead of prepared statements. While total and count come from db-column-int (trusted source), this breaks the pattern established elsewhere. For consistency and defense-in-depth, should use prepared statements.

2. Statement Finalization on Error Paths

In several functions, error paths may leak prepared statement handles. Example at list-products line 271 - the comment acknowledges needing to clean up stmt but doesn't finalize. Also affects list-cart:338 and potentially others where db-prepare fails but returns a handle.

3. Race Conditions in Cart Operations

Issue: Multiple concurrent requests can create race conditions. Scenario: Two requests checkout simultaneously - both read cart total, both deduct stock, stock gets double-deducted.

Current mitigation: Each connection has its own DB handle, but SQLite allows concurrent reads. The check-stock-available helps but doesn't fully prevent TOCTOU issues.

Recommendation: Consider using SQLite's locking or adding application-level serialization for checkout operations.

4. Error Messages Leak Implementation Details

Lines 686-687 expose Database error to clients. For production use, avoid exposing implementation details. Generic Internal Server Error is safer.

5. Missing Content-Type for Error Responses (Minor)

The http-error, http-bad-request, and http-not-found helpers set Content-Type: text/plain, but line 686 hardcodes the response without it. Should be consistent.

Test Coverage

The PR includes manual testing (curl examples), which is good for a demo. Consider adding concurrent test scenarios, edge cases (checkout with item that just went out of stock), and malformed input testing.

Performance Considerations

  1. Good: Each request has isolated DB connection (simplifies concurrency)
  2. Trade-off: Opening/closing DB per request adds overhead. For high throughput, consider connection pooling.
  3. Query efficiency: Joins are appropriate, and ORDER BY id uses indexed column.

Security Summary

  • SQL injection in user inputs: HIGH - Fixed in commit 2
  • SQL injection in create-order: MEDIUM - Needs attention
  • Information disclosure: LOW - Minor issue
  • Race conditions: MEDIUM - Acceptable for demo

Documentation Quality

  • README: Excellent - covers build, API, testing, features
  • Code comments: Good stack effects, clear section headers
  • sqlite.toml: Outstanding documentation of prepared statement API
  • Commit messages: Very thorough, documents all changes

Educational Value

This is an excellent learning example because it demonstrates:

  • Real-world FFI usage (prepared statements, transactions)
  • HTTP server patterns in concatenative style
  • Concurrent request handling
  • Input validation and error handling
  • Multi-table database operations

Recommendation

Approve with suggestions - The second commit shows excellent responsiveness to feedback by fixing the critical SQL injection issues. The remaining items are mostly about consistency (create-order) and edge cases. For a demo/example, this is high quality.

Priority fixes before merge:

  1. Fix create-order to use prepared statements (consistency)
  2. Ensure all error paths finalize statements (prevent leaks)

Nice-to-have:
3. More generic error messages for production readiness
4. Document the concurrency model and its limitations

Overall: This is a strong contribution that significantly enhances the examples. The code quality is good, security issues from commit 1 were properly addressed, and it serves as an excellent reference for Seq developers. Well done!

Lines referenced:

  • SQL injection fix: examples/shopping-cart/shopping-cart.seq:346-401
  • Transaction handling: examples/shopping-cart/shopping-cart.seq:481-541
  • Statement API: examples/shopping-cart/sqlite.toml:81-212
  • Create order issue: examples/shopping-cart/shopping-cart.seq:462-473

  1. create-order now uses prepared statements:
  - Changed from string concatenation to db-prepare with db-bind-int
  - Added proper statement finalization on both success and error paths

  2. Statement leak fixes:
  - Fixed all error paths to call db-finalize before returning
  - Functions fixed: seed-products, list-products, list-cart, add-to-cart, remove-from-cart, calculate-cart-total, check-stock-available, collect-products, collect-cart-items

  3. Critical db-step/db-finalize bug fix:
  - db-step consumes the statement handle, so we need dup db-step drop to preserve it for db-finalize
  - Fixed in: add-to-cart, remove-from-cart, create-order
@claude
Copy link
Copy Markdown

claude Bot commented Dec 13, 2025

PR Review: Shopping Cart Example and SQLite Prepared Statements

Summary

This PR adds a comprehensive shopping cart REST server example that demonstrates SQLite FFI with prepared statements, transactions, and concurrent request handling. The author has already addressed several rounds of feedback regarding SQL injection, input validation, and statement leak fixes.

✅ Strengths

Security

  • Excellent SQL injection prevention: All user inputs now properly use prepared statements with db-bind-int and db-bind-text
  • Input validation: Query parameters are validated (presence, numeric parsing, positive values)
  • Stock validation: check-stock-available prevents overselling before checkout
  • Transaction safety: Proper BEGIN/COMMIT/ROLLBACK pattern with rollback on all error paths

Code Quality

  • Resource management: Comprehensive db-finalize calls on all paths (success and error)
  • Clear documentation: Well-commented code with stack effects and inline explanations
  • Good separation of concerns: HTTP, database, and business logic clearly separated
  • Consistent error handling: All database operations check return codes and finalize on errors

Example Value

  • Comprehensive demonstration: Shows FFI, prepared statements, transactions, concurrency, HTTP routing, and query parsing
  • Production-like patterns: Uses realistic e-commerce scenarios with proper validation
  • Educational: Clear comments explain SQLite API usage patterns

🔍 Issues Found

1. CRITICAL: Race Condition in Concurrent Cart Access (shopping-cart.seq:693-712)

Each HTTP request gets its own database connection, but the cart and checkout operations are not isolated per user/session. Multiple concurrent requests could add items to the same global cart simultaneously or race during checkout.

Impact: Cart items appearing/disappearing, stock going negative, orders with incorrect totals

Recommendation: Document this as a single-user cart limitation, OR add session management, OR use BEGIN IMMEDIATE/EXCLUSIVE

2. Statement Handle Leak Risk in Error Paths (shopping-cart.seq:358-398)

In add-to-cart, error path clarity could be improved. SQLite's sqlite3_finalize handles NULL gracefully, but adding a comment would help.

Severity: Low
Recommendation: Add comment explaining NULL finalize safety

3. Missing Error Information

Database failures return generic messages without using db-errmsg for actual SQLite error details, making debugging difficult.

Recommendation: Use db-errmsg to include actual error messages

4. update-stock SQL Efficiency (shopping-cart.seq:472-476)

The query repeats the same subquery 3 times. Consider using a JOIN-based UPDATE for better performance.

5. No Automated Tests

Manual curl examples provided but no automated integration tests for transactions, concurrency, and edge cases.

Recommendation: Add test file for cart operations, edge cases, and transaction rollback

6. Documentation: Stock Race Condition (shopping-cart.seq:469-477)

Comment should explain the two-phase check pattern (check-stock-available + WHERE clause atomic check).

🎯 Minor Suggestions

  • Line 684: Method not allowed should be HTTP 405, not 400
  • Line 715: worker function name is generic, consider connection-worker or request-handler
  • FFI manifest duplication: examples/shopping-cart/sqlite.toml vs examples/ffi/sqlite/sqlite.toml - document why

📊 ROADMAP.md Changes

  • ✅ Correctly updates ffi:readline to ffi:libedit
  • ✅ Documents callback shelving with clear reasoning
  • ✅ Updates tab completion section appropriately

🏆 Overall Assessment

Rating: Approve with Minor Recommendations

High-quality example demonstrating advanced FFI patterns. Author has been responsive and fixed all critical security issues.

Completed:

  • ✅ SQL injection prevention
  • ✅ Input validation
  • ✅ Statement leak fixes
  • ✅ Stock validation

Recommended for follow-up:

  1. Document single-user cart limitation
  2. Fix update-stock SQL efficiency
  3. Add automated tests
  4. Improve error messages with db-errmsg

The code is production-ready as an EXAMPLE and provides excellent educational value for learning Seq's FFI system.


Excellent work on this comprehensive example! The iterative improvements show great attention to security and correctness.

@navicore navicore merged commit 41334c9 into main Dec 13, 2025
2 checks passed
@navicore navicore deleted the shopping-cart branch December 13, 2025 05:41
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant