今日已更新 266 条资讯 | 累计 25816 条内容
关于我们

标签:#t

找到 12290 篇相关文章

AI 资讯

Clear the Lineup — doesNotEqual was always true for single-select survey answers in Formbricks

This is a submission for DEV's Summer Bug Smash: Clear the Lineup . Project Overview Formbricks is an open-source survey and experience-management platform. Its packages/surveys package ships the client-side survey runner, and inside it, packages/surveys/src/lib/logic.ts is the module that decides, for every question and every "skip logic" / branching rule a survey author configures, whether a given condition ( equals , doesNotEqual , contains , isEmpty , and friends) is true for a respondent's answer. This is pure, unglamorous logic — but it's load-bearing: it's what routes respondents through the correct sequence of questions. I picked up issue #8527 for the "Clear the Lineup" track, which reports that doesNotEqual conditions weren't behaving correctly for single-choice questions. Bug Fix or Performance Improvement The doesNotEqual operator is supposed to be the exact logical negation of equals . For most answer shapes it was. But for MultipleChoiceSingle answers, the survey runtime sometimes represents the selected value as a single-element array rather than a bare string (this happens via getLeftOperandValue , e.g. when a choice answer is merged with an "other" option path). To handle that shape, both equals and doesNotEqual had a special-case clause that unwraps a one-element array and compares its only entry to the right-hand value. equals 's fallback: return ( ( Array . isArray ( leftValue ) && leftValue . length === 1 && typeof rightValue === " string " && leftValue . includes ( rightValue )) || leftValue === rightValue ); doesNotEqual 's fallback (before the fix): return ( ( Array . isArray ( leftValue ) && leftValue . length === 1 && typeof rightValue === " string " && ! leftValue . includes ( rightValue )) || leftValue !== rightValue ); At a glance this looks like a faithful "negate every sub-expression" mirror of equals . It isn't. The array-includes clause was correctly inverted ( !leftValue.includes(rightValue) ), but the second disjunct, leftValue !==

2026-07-18 原文 →
AI 资讯

FAM CTF : The Vault Door Writeup

Summary NexaVault is a mock internal dashboard app that gates an "Admin Vault" panel behind a role claim in a JWT. The app issues a user-role token on login, stored in the nx_access cookie, and trusts the claims inside it without properly re-verifying the signature on every request. Recon Logged in as a normal user ( strawhat ) and captured the request to /famctf/dashboard : Cookie: nx_access=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJzdHJhd2hhdCIsInJvbGUiOiJ1c2VyIn0.x5PRC4_NFw5cGM02QklUN5yq6rtGOMP_E8bKGxgIbME Decoding the JWT: Header { "alg" : "HS256" , "typ" : "JWT" } Payload { "sub" : "strawhat" , "role" : "user" } The dashboard UI showed an "Admin Vault" card locked behind Admin only , confirming role was the authorization check. Attempt 1 - Naive tampering (failed) Editing the payload directly to "role":"admin" while keeping the original HS256 signature predictably failed - the signature no longer matched the modified payload, and the server redirected to the login page. This confirmed the server does verify the signature against the payload, but didn't yet confirm how strictly it verifies the algorithm itself. Attempt 2 - alg:none bypass (success) Many JWT libraries historically honor the alg field declared in the token header to decide how to verify, including a none algorithm meant for unsigned/pre-verified tokens. If the server-side verification doesn't explicitly reject none , an attacker can forge any payload with zero knowledge of the signing secret. Forged header: { "alg" : "none" , "typ" : "JWT" } Forged payload: { "sub" : "strawhat" , "role" : "admin" } Forging Script import base64 , json def b64url ( data : bytes ) -> str : return base64 . urlsafe_b64encode ( data ). rstrip ( b ' = ' ). decode () header = { " alg " : " none " , " typ " : " JWT " } payload = { " sub " : " strawhat " , " role " : " admin " } h = b64url ( json . dumps ( header , separators = ( ' , ' , ' : ' )). encode ()) p = b64url ( json . dumps ( payload , separators = ( ' , ' ,

2026-07-18 原文 →
AI 资讯

Stashr has officially launched

What launched Stashr started as an invite-only waitlist, then opened up as a free public beta . Today it leaves beta for good. That means three things: It's a finished product, not a preview. Everything the beta promised as "coming next" is live: AI tagging, meaning-based search across your media, and a full agent stack. Nothing on this page is a maybe. Pricing is real. Stashr is now a paid app with a 7-day free trial and no permanent free tier. More on the plans below. It's stable. Thousands of saves, big bulk imports, deleted-post edge cases, and the weird stuff you all threw at it during beta are handled. Thank you for breaking it. It's much sturdier for it. If you're new here, the fastest way in is to [create an account(/signup), install the browser extension , and keep saving the way you already do. What Stashr actually is In one line: it's a capture-first bookmark manager. The moment you save something on any platform, Stashr copies the full post into a private library that's genuinely yours, then tags it and makes it searchable in plain English. That "copy" part is the whole point. A normal bookmark is just a pointer at someone else's servers. The day the author deletes the post, goes private, or gets suspended, your save resolves to nothing. Stashr keeps a real copy, so what you saved is still there months later even when the original is gone. If you've ever wondered where your saved posts actually go or watched your links quietly rot into 404s , that's the gap this closes. It works in three moves: Capture A browser extension watches for saves on the platforms you already use. Bookmark on X , favorite on TikTok , save on Reddit , tap the ribbon on Instagram , exactly as you always have, and the full post lands in Stashr automatically. You don't change a single habit. A bulk import pulls in the backlog you already built too. Organize Every save is read and auto-tagged by AI on the way in, so the filing happens for you. No folders to babysit, no tagging discip

2026-07-18 原文 →
开发者

Sony’s flagship RGB LED TV is incredible

The Sony Bravia 9 II is the most anticipated new TV in years. It's an amazing RGB LED TV. I watched Dungeons & Dragons: Honor Among Thieves on the new Bravia with my son, who has been getting into the roleplaying game but had never seen the movie. The landscapes of Faerûn looked natural and […]

2026-07-18 原文 →
AI 资讯

Clear the Lineup — Chasing a Stack Overflow in Typst's `#eval` Down to One Wrong Word

This is a submission for DEV's Summer Bug Smash: Clear the Lineup . Project Overview Typst is the Rust-based markup typesetting system that's been quietly eating LaTeX's lunch for the last couple of years — you write plain-text markup, Typst compiles it to PDF (or HTML) with a real incremental compiler underneath instead of a multi-pass macro soup. Part of what makes it pleasant is that it exposes its own evaluator to itself: a document can call #eval("some typst code") and get back whatever that code produces, at runtime, inside the document being compiled. It's a small feature, but it opens up a surprisingly deep rabbit hole, which is exactly where this bug was hiding. Bug Fix or Performance Improvement The problem: typst/typst#8632 reports that Typst crashes instead of erroring when #eval is used to recursively re-import the file it's running in. The repro is one line. Save this as overflow.typ : #eval("import \"overflow.typ\"") Then: $ ./target/debug/typst compile overflow.typ overflow.pdf thread 'main' (750833) has overflowed its stack fatal runtime error: stack overflow, aborting No PDF, no diagnostic, no exit code you can act on — just a native stack overflow and a SIGABRT. Typst has had cyclic-import detection since forever; a normal top-level import "overflow.typ" inside itself gets caught cleanly with an error: cyclic import message. Something about routing the import through #eval specifically was bypassing that check. The hunt I'll be upfront about how this investigation actually went: I worked through it with Claude (Anthropic's coding agent) rather than solo. The triage pass it did before I sat down with the code had already narrowed the search to one function — eval_string in crates/typst-eval/src/lib.rs — and named the suspect line. That's a big head start, but a named suspect isn't a confirmed root cause, so the actual work was reading that function next to its sibling, the file-level eval() a few lines above it, and checking the claim against the s

2026-07-18 原文 →
AI 资讯

I built a workflow that forces AI agents to teach you the code they write

As a developer, I got a bit scared and fed-up of blindly merging massive pull requests and losing context on my own codebase, so I built FluencyLoop . https://github.com/baokhang83/fluencyloop It is an open-source, local-first workflow plugin for Claude Code and Codex that ensures your code and your codebase fluency are produced together. Instead of letting an agent dump raw code, it tracks your technical familiarity locally and pauses to explain complex architectural choices or rejected alternatives only on topics you do not know yet. It also produces documentation and tracks the decisions it makes along the way. Try it out ! It feels really good to get the AI caring for my understanding 🤣

2026-07-18 原文 →
AI 资讯

Scaling a Single React App to 71+ Browser-Based Tools Without Killing Load Time

The problem with "just add another tool" When you're building one image tool, performance is easy. When you're building 71 of them in the same app — resize, compress, crop, PDF merge, format converters, exam-photo presets, social media templates — the naive approach (import everything, bundle it all together) turns your app into a multi-megabyte JavaScript payload before a user has even picked a tool. This is the actual engineering problem behind ResizeHub , which now has 71+ tools across 11 categories, all running client-side with zero server uploads. Here's how the architecture holds up at that scale. Stack, and why each piece earns its place React + TypeScript — type safety matters more, not less, as tool count grows. A shared ImageProcessor interface that every tool implements catches integration bugs at compile time instead of in production. Vite — its native ES modules dev server and Rollup-based production build made code-splitting dramatically easier to reason about than older bundlers, which matters a lot once you have dozens of independent tool routes. HTML5 Canvas API — the actual compression/resize/crop engine, shared across tools rather than reimplemented per-tool. Cropper.js — for interactive cropping UI specifically (aspect-ratio locking, circular crop for signatures) rather than rebuilding drag-handle math from scratch. Pica — for high-quality image downscaling; the browser's native canvas scaling can introduce visible aliasing on large downscales, and Pica's algorithm handles this noticeably better. Cloudflare Pages — static hosting with edge caching, which matters since 100% of the actual processing work happens in the user's browser, not on any server at all. Lesson 1: Route-level code splitting isn't optional past a handful of tools With React Router and dynamic import() , each tool becomes its own chunk: const PhotoResizer = lazy (() => import ( ' ./tools/PhotoResizer ' )); const PdfCompressor = lazy (() => import ( ' ./tools/PdfCompressor ' ));

2026-07-18 原文 →
AI 资讯

The Real Moat in Legal AI Isn't the Model—It's the Data

A closer look at why companies like EvenUp are difficult to compete with, and what this means for the future of AI-powered legal technology. Introduction A few weeks ago, I went down a rabbit hole trying to understand how EvenUp built one of the most successful AI products in personal injury law. Like many people, I assumed the competitive advantage would come from a proprietary large language model, sophisticated prompt engineering, or some secret AI architecture hidden behind the scenes. Instead, I found something much less glamorous—but far more valuable. There is no magical prompt. There is no proprietary model that nobody else can build. The real competitive advantage is data. Hundreds of thousands of real personal injury cases. Millions of medical records. Actual settlement outcomes connected to real case facts. Years of attorney corrections, paralegal feedback, negotiations, settlements, and litigation outcomes—all continuously improving the system. Once you realize this, you begin to see the same pattern across almost every successful vertical AI company. The model is rarely the moat. The data is. Why "AI for X" is mostly noise right now Today, almost every industry has dozens of startups claiming to build: AI for law firms AI for healthcare AI for accounting AI for insurance AI for real estate Scratch beneath the surface, however, and many of these companies are built on the same foundation: GPT Claude Gemini Llama The underlying model changes every few months. The interface changes. The branding changes. The product positioning changes. But underneath, many products are simply orchestration layers around publicly available foundation models. That isn't inherently bad. Good user experience matters. Workflow automation matters. Tool integrations matter. But none of those create a durable competitive advantage. Anyone with API access, a competent engineering team, and enough time can recreate that layer. What they cannot recreate overnight is years of proprie

2026-07-18 原文 →
AI 资讯

📓 I Built an AI App That Makes Learning English Feel Effortless

📓 Stop Memorizing English — I Built an AI App That Actually Works ⚡ The Hook You try to learn English. You memorize words. And then… you forget them. 🧠 The Real Problem Most people learn English the wrong way: memorizing random word lists switching between apps and dictionaries learning without context That’s why nothing sticks. 🚀 The Idea What if learning English felt like this: 👉 You read something interesting 👉 You click a word you don’t know 👉 You instantly understand it No interruptions. No friction. ✨ Introducing: English Notebook A modern AI-powered app where you learn English by interacting with real content . generate stories click unknown words build vocabulary automatically 🤖 Generate Stories Based on Your Level This is one of the most powerful features. You choose your level: A1 → Beginner A2 B1 B2 C1 C2 → Advanced And the app generates a custom story just for you . 🖼️ Story Generator 📖 Learn by Clicking Words No more: copy-pasting opening dictionary tabs losing focus Just click any word: definition translation (your language 🌍) example sentences 🖼️ Word Interaction 📚 Smart Vocabulary Notebook Every word you click: 👉 automatically saved 👉 turned into a flashcard You can: review anytime mark as mastered ✅ 🖼️ Vocabulary Notebook 📊 Track Your Progress (Game Changer) This is where things get serious. You don’t just learn — you measure your growth . Dashboard shows: total words learned active vs mastered words daily streak 14-day activity trend 🖼️ Dashboard What gets measured gets improved. 🕘 Nothing Gets Lost (History System) Every story you generate is saved. You can: revisit old stories continue reading anytime track your learning journey 🖼️ History 🔊 Learn with Audio listen to stories follow highlighted words improve pronunciation naturally 🌍 Multi-Language Support You can choose your translation language: Persian 🇮🇷 Arabic Spanish Hindi and more 🎯 Why This App Is Different Most apps: ❌ force memorization ❌ feel like school ❌ break your focus English Note

2026-07-18 原文 →
AI 资讯

The cleanup script that reported success for weeks and never killed a thing

I wrote a cleanup routine that matched processes by command line with a wildcard pattern. It reported success on every run. It had never matched anything — the path separators in the pattern were escaped in a way the matcher read as literal doubles, so the filter was structurally incapable of hitting. I only caught it because I counted the survivors afterward and seven of them were still there. The fix was switching from a wildcard match to a plain substring containment check with no escape semantics at all. A filter that cannot fail loudly will lie to you politely forever. Before trusting any matcher, feed it a known-positive and watch it fire — a green result from an instrument you never saw go red is noise. What's the equivalent lesson your worst bug taught you?

2026-07-18 原文 →
产品设计

The apps, gadgets, and tools every reader needs

Hi, friends! Welcome to Installer No. 136, your guide to the best and Verge-iest stuff in the world. (If you're new here, welcome, hope your neighborhood isn't as smoky as mine, and also you can read all the old editions at the Installer homepage.) This week, I've been recording the next season of Version History […]

2026-07-18 原文 →
AI 资讯

More games should be on rails (literally)

It's been a good few weeks for games on rails. Nintendo's Star Fox remake wisely kept the tightly scripted, action-packed levels from Star Fox 64 largely the same, and they're still fun to fly through nearly 20 years later. Denshattack!, a new game from Undercoders, similarly features levels packed with carefully orchestrated sequences to great […]

2026-07-18 原文 →
AI 资讯

The Missing Row: Auto-Provisioning Derived Records Without the Race Condition

Why some records should be created by your system, not your users, and how to do it safely in .NET. A support ticket lands on your desk: "The Teams page is empty. I added a member, but no team shows up." You check the API. It's behaving exactly as written: { "items" : [], "totalCount" : 0 } Nothing is broken. And that's the problem. The system is faithfully returning nothing, because the row that the page reads from was never created. Somewhere in your design, you assumed a human would create it first. This article is about a small, recurring design decision that quietly causes empty dashboards, confused users, and "is this a bug?" tickets: who is responsible for creating derived records the user, or the system? and how to let the system do it without introducing duplicate rows or race conditions. The problem Let's use a fictional product: a collaboration tool called Loop . In Loop, the important entities are: An Organization (a paying customer). A Member (a person invited into an organization under a plan). A Team a grouping that members belong to, keyed by (OrganizationId, PlanCode) . The admin dashboard lists Teams . Each team card shows a member count. Here's the catch in the original design: creating a Member wrote a member row. Creating a Team was a separate, manual step an admin was expected to do first. If an admin invited members without first creating the matching team, the dashboard showed nothing even though the members clearly existed. From the user's point of view, they did everything right. From the system's point of view, a required row simply didn't exist. Why it matters The Team record isn't independent information. It is fully derivable from the first member invited under a plan. When one entity's existence is implied by another, forcing a human to create it manually is a design smell. It leads to: Empty states that look like outages. Users can't tell "no data" from "misconfigured." Support load. Every skipped step becomes a ticket. Silent data dr

2026-07-18 原文 →
AI 资讯

Vite SPA vs Next.js SSR: Real Performance Differences After Migration (With Benchmarks)

The Architectural Shift: Client-Side vs Server-Side For years, the standard for building modern React applications was the Single Page Application (SPA). Vite revolutionized this space by providing an incredibly fast developer experience (DX) and an optimized build process. However, as applications grow, many teams find themselves hitting the performance ceiling of client-side rendering. When we talk about migrating from a Vite-based SPA to Next.js, we aren't just changing build tools; we are moving from a model where the browser does all the work to a model where the server shares the load. In this article, we'll look at the benchmarks of a mid-sized e-commerce dashboard before and after migration. Understanding the Core Metrics To measure the impact truly, we focus on three Core Web Vitals: LCP (Largest Contentful Paint): How quickly the main content is visible. FID (First Input Delay): How responsive the page is to the first interaction. CLS (Cumulative Layout Shift): How stable the visual elements are during loading. Vite SPA Performance (The Baseline) In a Vite SPA, the initial HTML request returns a nearly empty <body> tag with a <script> bundle. The browser must: Download the HTML. Download the JavaScript bundle. Parse and execute the React code. Fetch data from an API. Finally, render the UI. Benchmark Results: LCP: 2.4s (on 4G connection) FID: 45ms TBT (Total Blocking Time): 320ms While the DX is lightning fast, the user experience suffers from the "white screen of death" during the initial bundle download. Next.js SSR/ISR Performance (The Post-Migration Result) Next.js changes this via Server-Side Rendering (SSR) or Incremental Static Regeneration (ISR). The server fetches data and pre-renders the HTML. The browser receives a fully formed UI immediately. Benchmark Results: LCP: 0.8s (on 4G connection) FID: 55ms TBT: 180ms There is a slight increase in FID because the browser's main thread is busy "hydrating" the static HTML into an interactive React app, b

2026-07-18 原文 →